Well, first I should probably ask if this is browser dependent.
I've read that if an invalid token is found, but the section of code is valid until that invalid token, a semicolon is inserted before the token if it is preceded by a line break.
However, the common example cited for bugs caused by semicolon insertion is:
return
_a+b;
..which doesn't seem to follow this rule, since _a would be a valid token.
On the other hand, breaking up call chains works as expected:
$('#myButton')
.click(function(){alert("Hello!")});
Does anyone have a more in-depth description of the rules?
Regarding semicolon insertion and the var statement, beware forgetting the comma when using var but spanning multiple lines. Somebody found this in my code yesterday:
It ran but the effect was that the srcIds declaration/assignment was global because the local declaration with var on the previous line no longer applied as that statement was considered finished due to automatic semi-colon insertion.
First of all you should know which statements are affected by the automatic semicolon insertion (also known as ASI for brevity):
var
statementdo-while
statementcontinue
statementbreak
statementreturn
statementthrow
statementThe concrete rules of ASI, are described in the specification §11.9.1 Rules of Automatic Semicolon Insertion
Three cases are described:
When a token (
LineTerminator
or}
) is encountered that is not allowed by the grammar, a semicolon is inserted before it if:LineTerminator
.}
e.g.:
is transformed to
The
NumericLiteral
1
meets the first condition, the following token is a line terminator.The
2
meets the second condition, the following token is}
.When the end of the input stream of tokens is encountered and the parser is unable to parse the input token stream as a single complete Program, then a semicolon is automatically inserted at the end of the input stream.
e.g.:
is transformed to:
This case occurs when a token is allowed by some production of the grammar, but the production is a restricted production, a semicolon is automatically inserted before the restricted token.
Restricted productions:
The classic example, with the
ReturnStatement
:is transformed to
Straight from the ECMA-262, Fifth Edition ECMAScript Specification:
I could not understand those 3 rules in the specs too well -- hope to have something that is more plain English -- but here is what I gathered from JavaScript: The Definitive Guide, 6th Edition, David Flanagan, O'Reilly, 2011:
Quote:
Another quote: for the code
and:
So I think to simplify it, that means:
In general, JavaScript will treat it as continuation of code as long as it makes sense -- except 2 cases: (1) after some keywords like
return
,break
,continue
, and (2) if it sees++
or--
on a new line, then it will add the;
at the end of the previous line.The part about "treat it as continuation of code as long as it makes sense" makes it feel like regular expression's greedy matching.
With the above said, that means for
return
with a line break, the JavaScript interpreter will insert a;
(quoted again: If a line break appears after any of these words [such as
return
] ... JavaScript will always interpret that line break as a semicolon)and due to this reason, the classic example of
will not work as expected, because the JavaScript interpreter will treat it as:
There has to be no line-break immediately after the
return
:for it to work properly. And you may insert a
;
yourself if you were to follow the rule of using a;
after any statement: