Automatic Semicolon Insertion & Return Statements

Automatic semicolon insertion & return statements

The javascript interpreter/compiler is so smart to only insert automatic semicolons if afterwards there is valid Javascript.

Your code works, because && b as it stands is no valid expression - that's why no semicolon gets inserted after the return a resulting in:

return a && b && c;

However:

return (undefined);//implicitely inserted
{
....
}

is perfectly valid and thats why a semicolon gets inserted.

For completeness' sake the ref to the spec: automatic semicolon insertion. THe examples are worth reading through.

What are the rules for JavaScript's automatic semicolon insertion (ASI)?

First of all you should know which statements are affected by the automatic semicolon insertion (also known as ASI for brevity):

  • empty statement
  • var statement
  • expression statement
  • do-while statement
  • continue statement
  • break statement
  • return statement
  • throw statement

The concrete rules of ASI, are described in the specification §11.9.1 Rules of Automatic Semicolon Insertion

Three cases are described:

  1. When an offending token is encountered that is not allowed by the grammar, a semicolon is inserted before it if:
  • The token is separated from the previous token by at least one LineTerminator.
  • The token is }

e.g.:

    { 1
2 } 3

is transformed to

    { 1
;2 ;} 3;

The NumericLiteral 1 meets the first condition, the following token is a line terminator.

The 2 meets the second condition, the following token is }.


  1. 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.:

    a = b
++c

is transformed to:

    a = b;
++c;

  1. 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:

    UpdateExpression :
LeftHandSideExpression [no LineTerminator here] ++
LeftHandSideExpression [no LineTerminator here] --

ContinueStatement :
continue ;
continue [no LineTerminator here] LabelIdentifier ;

BreakStatement :
break ;
break [no LineTerminator here] LabelIdentifier ;

ReturnStatement :
return ;
return [no LineTerminator here] Expression ;

ThrowStatement :
throw [no LineTerminator here] Expression ;

ArrowFunction :
ArrowParameters [no LineTerminator here] => ConciseBody

YieldExpression :
yield [no LineTerminator here] * AssignmentExpression
yield [no LineTerminator here] AssignmentExpression

The classic example, with the ReturnStatement:

    return 
"something";

is transformed to

    return;
"something";

Can someone explain me how the empty statement in javaScript is affected from Automatic Semicolon Insertion

Read the spec linked from the MDN page. The empty statement is "affected" because ASI won't be done if the inserted semicolon would result in an empty statement.

Hand-wringing over when ASI happens can be dispensed with by simply including semicolons explicitly. The most common pitfall of ASI is the return statement, when attempting something like

return
{ propertyName: "something" };

Don't do that. Start the object initializer on the same line as the return.

As to the difference between a semicolon and an empty statement: a semicolon is a boundary. In the following code:

var x; ;

There's a var declaration statement, then an empty statement. The second semicolon is not part of the empty statement, but it implies that there is an empty statement before it.

Javascript automatic semicolon insertion for do-while statements

I'm pretty sure that "case" added in ES2015 is only there to standardize rules which browsers had already implemented in order to be compatible with terribly-written (or weirdly minified) scripts. It wasn't exactly a new feature, so much as it was a tweak of the specification to be in line with what browsers were doing already.

For example, your snippet runs in IE11, which was released in 2013:

do {} while (false) var a = 42;console.log('no parse errors');

Why is JavaScript designed to automatically insert a semicolon after a return followed by a new line?

The exact reasons why are probably lost in the mists of time. I'm willing to bet that it happened something like this:

  • At some point, somebody thought it would be a good idea to make semicolons optional at the end of statements.
  • Later on, somebody else noticed an ambiguity in the syntax when semicolons were omitted when used with return statements in the way you describe.
  • The formal language specification was then amended with the confusing new rule about omitted semicolons on return statements, to codify current practice rather than changing the rules to make sense.

Why does a return statement on a new line not return any value?

The "rule" is automatic semicolon insertion.

return is a valid statement all on its own, so it is treated as a complete statement. The code starting on the next line is also syntactically valid (although it's not interpreted as an object at all in this case, but rather a code block containing a label and a single "statement" that consists of a string literal). So automatic semicolon insertion kicks in here and the two are treated as separate statements.

The code that starts on the line after the return is simply ignored.

Note that some IDEs and linters can help with this, since you essentially have unreachable code. Here is a screenshot of how VSCode's default syntax highlighting displays the two functions. You can see that the hello: world is shaded a dull color in the second function:

Screenshot of VSCode showing unreachable code.

Why does a multiline comment cause automatic semicolon insertion?

This is expected, it's working as designed. The ES6 specifiction says the following on the grammar for comments:

Comments behave like white space and are discarded except that, if a
MultiLineComment contains a line terminator code point, then the
entire comment is considered to be a LineTerminator for purposes of
parsing by the syntactic grammar.

And this LineTerminator then causes automatic semicolon insertion to kick in, following the usual rules.



Related Topics



Leave a reply



Submit