I received such a letter from Shaun Silva last night:
I was reviewing your code for the npm.js project (specifically this file: https://github.com/isaacs/npm/blob/master/lib/npm.js ), and noticed that you align commas under 'r 'in var expressions, and under [and {in array / object literals. I really like this way of formatting, but I hesitate to use it, since most of the resources about js instill fear of the chaos that reigns in the code due to the automatic semicolon if you don’t finish the lines with something that suggests continued
Is it safe to place commas in this way in the “browser” code, or is it only possible in a node?
I wrote several paragraphs, and decided to shorten them to the following answer:
Yes, it is completely safe, and it is a completely valid JS, understood by every browser. Closure compiler, yuicompressor, packer, and jsmin - everyone can properly minify it. Productivity will not anywhere.
I am sorry that instead of teaching you, the leaders of this language’s community instilled in you lies and fears. It's a shame. I recommend learning how the JS instructions are actually terminated (and in which cases they are non-determinable) —and you can write code that you find fine.
Inimino posted a
very clear explanation . In his style - clear, clear, authoritative, with good research - and he, as always, kept his opinion to himself.
I'm going to be a little more biased.
rules
In general,
\n
always ends expressions, except for the following cases:
- The expression carries an unclosed parenthesis, an array literal, an object literal, or ends in any other way that is not a legal way to close an expression (for example, ends with
.
Or); - The string is a
--
, ++
(in the event that the next token is decremented / incremented); - These are
for()
, while()
, do
, if()
, or else
, and there is no line {
- The next line starts with
[
, (
, +
, *
, /
, -
,,, .
, Or any binary operator that can be in one expression only between two tokens.
The first rule is pretty obvious. Even JSLint does not object to
\n
characters in JSON, in constructions with brackets, and in
var
expressions that extend over several lines ending in,.
The second is very strange. I have never met such things (except for these kinds of conversations) that someone would like to write
i\n++\nj
, but, in fact, it is parsed as
i; ++j
i; ++j
, not like
i++; j
i++; j
The third is well understood, although they are usually neglected:
if (x)\ny()
equivalent to
if (x) { y() }
. This construct does not end until a block or expression is encountered.
;
is a valid JavaScript expression, so
if(x);
is equivalent to
if(x){}
or "if x, do nothing." This usually applies to cycles in which the check is also an update of the counter. Unusually, but occurs.
The fourth, usually
FUD suggestive, “oh, neta, you need a semicolon!” Is the case. But it turns out, it’s quite simple to prefix such lines with semicolons if you didn’t want to make them continue with the previous ones.
For example, instead of:
foo(); [1,2,3].forEach(bar);
can write:
foo() ;[1,2,3].forEach(bar)
The advantage is that prefixes are
easier to notice, since you decided to never start a line with
(
or
[
without a semicolon.
Limited rule
Another standard argument for semicolons is related to AIS and restricted rules. For example, if you have
\n
right after the token
return
,
throw
,
break
,
continue
, or
++
or
--
in postfix form (for example,
x++\n
or
y--\n
), then this will end the expression - without exception .
And once again: in spite of this, it is
easier to notice and prevent such things as soon as you unaccord yourself with completing each expression with a semicolon. When I meet the second rule, my brain instinctively associates
\n
c "ok, that's all," because a
return
always enough to terminate
return
.
Aligning the most important tokens on the left side of the screen makes them clearly easier for quick human analysis. Piles of fast-reading studies and eye movements state that the missing token on the right is overlooked more likely than the missing token on the left. So - I repeat - move less important things to the right, and put more important things to the left.
')
So which style is better?
To the extent that there is an objectively “best style” at all, it seems to me that the “minimum commas / commas first” style is
slightly better; for two reasons: because this style is better readable and because it encourages developers to better understand the language they use.
I can guarantee that no matter how little you care, my JS code worries me less than mine cares about you. This is not an article where I try to convince you to write code in my style.
Everyone must decide what the policy of wearing pants in his house .
As a manifestation of goodwill ...
Good reasons to dot the semicolon
The reasons for the overuse of semicolons are aesthetics and politics.
"I put semicolons in JS, because otherwise it will not be valid C / C ++ / Java / More." If you have to write a lot of Java or C code in a project, and you want your JS to not stand out too much, then this is a good argument. (Project
Cassis brings this argument to an absurd conclusion).
"We do it because we use a linter, and the linter tells it so." Consistency is important, and linters are one of the ways to achieve code consistency for a group. The task of writing a linter that is compatible with npm is on my todo list, but not very high.
The most terrible reasons everywhere to put a semicolon
“They are mandatory because ASI is unreliable” Oh, come on ??
These rules go back to the dawn of the JS, to the late 90s. They are not new, and my opinion - there is no forgiveness to anyone who calls himself a professional in JS and does not understand the rules for interrupting expressions.
It is frankly irresponsible on the part of the JS community leaders to continue spreading ambiguity instead of understanding.Moreover, the typical place where AIS attacks by sneak is limited rules.
Adding semicolons in each line will not force return\nfoo
return anything other than undefined
. The problem is that you
use a newline , and not that you
do not put a semi-colon .
The only way to
permanently prevent errors with limited rules is to always use semicolons and
never line breaks . No one offers this. So stop talking about it as if it matters, or suggest redundant semicolons as an alternative to understanding ASI. You must understand ASI to be a competent JS programmer, period.
And this leads us to the fact that ...
I become all of myself biased and enrage you (despite the noble attempt to do the opposite)
If you don’t understand how expressions are terminated in JS, then you simply don’t know JS properly, and you don’t have to write to JS professionally without supervision, and
definitely don’t give advice on how to write it.
I think I just insulted you. Very sorry. I know that you know a lot of things
about JS - such as DOM, and CSS, and MSIE bugs, and jQuery. You probably spent some time studying closures, and prototypes, and scopes, and activation objects, and even wrote several extensions for V8 or SpiderMonkey. You are not stupid, I am sure. In fact, you are probably smarter than me, and probably prettier and look better. I am sure: we have a lot in common, and we could be friends.
But if you do not understand
what an expression is in JS , then in your understanding of what is probably the most fundamental aspect of language is a huge hole.
And that's fine. I don't speak Spanish very well and my C is, in general, at a novice level; and I do not call myself an expert in these things - although I know enough to get out in most situations. If I was going to a job that involves a lot of conversations in Spanish or a lot of C - I would like someone to look after me in order to help avoid some serious mistakes.
Like most things in JS, the expression termination rules are
not well designed, but they are
not very difficult to understand and use. This understanding just takes a little time and effort.
Sit back with hot chocolate and the ECMAScript specification sometime Saturday night. Practice it. Play with the test programs. This is a good pastime.
Or do not do it if you do not want. This is your life. Surely you have better classes.
Just stop making authoritative statements like "end all lines with a semicolon to be safe." It is no safer or more reliable.
Addition 1: "Leaders"
So, mr-ironing-against-wool, who are these “leaders” that you are talking about? Why don't you name names?
Because there are so many of them, and I do not know them all.
If you have been writing to JS for some time and giving advice or supervising someone who has less experience, then I appeal to you. Being a leader is a responsibility. Take it seriously. Do not spread lies. Be an expert, or admit that you are not. But do not drive this car without a license.
Addition 2: Adepts of Literate Programming
(comment of the translator: literary programming means)But in English we put punctuation marks at the end, not at the beginning.
JavaScript is not English. We also do not denote possession (or an object-verb relation) using a point in English. There are no object literals in English, and we indent only the first line of the paragraph, not all sentences.
This is such a stupid argument that I have no choice but to fall in love with him.
I started to insult you, but you have won my heart, the Adept of Competent Programming. From now on, I will put line breaks only at the end of functions, not in the middle, and indent the first line of each of them.
Addition 3: Pedantry
What are you getting into my code? Are you a pedant stol?
Write the code as you wish. I don't have the slightest deal.
Just please don't lie to people. That is all I ask. This is only a small politeness. It is not difficult. Just tell the truth instead of lying - that's what I'm talking about.
(from the translator: as a translator, I want to express my gratitude for the help with the translation and proofreading work of my beloved philologist)