Article by Garrett Smith
This document is an addendum to Code Guidelines for Rich Internet Application Development.
Productions that are not restricted can be created accidentally where ASI has been used. This is often the result of where the developer forgot to use a semicolon. Regardless, the problems it creates can occur when the order of Statements changes or when line terminators are added or removed, including those that appear in comments. Where semicolons are needed, it is recommended that they appear explicitly.
The parentheses following an Expression interpreted as Arguments, implicating the Expression in a CallExpression:
var MyWidget = function(){ this.name = "mike"; } /** * Initialize Widget */ (function() { /*...*/ });
The FunctionExpression that appears on the right hand side of the assignment
to the identifier MyWidget
would be called because the parentheses,
which were intended to be a Grouping Operator, are interpreted as Arguments
in a CallExpression, resulting in MyWidget
having the value
undefined
and window.name
getting the value "mike"
.
This can be explained by the fact that a program is scanned from left to right, repeatedly taking the longest possible sequence of characters as the next input element. Since a CallExpression is not a restricted production, the program would be interpreted as:
var MyWidget = function(){ this.name = "mike"; }(function() {});
An ArrayLiteral can be interpreted as property accessor after the
removal of a restricted production. In this case, Expression g--
.
var g = 12 g-- [].slice.call([1,2,3])
The program is interpreted as:
var g = 12; g--; [].slice.call([1,2,3])
When the postfix operator is removed, a SyntaxError results. Given the input:
var g = 12 --g [].slice.call([1,2,3])
The program is interpreted as:-
var g = 12; --g[].slice.call([1,2,3])
- and that program is not valid syntax so it results in a SyntaxError.
A LineTerminator in any MultilineComment affects ASI. From ECMAScript Edition 5 specification, 5.1.2:
A MultiLineComment (that is, a comment of the form /*...*/ regardless of whether it spans more than one line) is likewise simply discarded if it contains no line terminator; but if a MultiLineComment contains one or more line terminators, then it is replaced by a single line terminator, which becomes part of the stream of input elements for the syntactic grammar.
Not all implementations follow rules of whitespace in MultiLineComment. JScript is one such implementation that does not process a MultiLineComment that contains a LineTerminator as a LineTerminator.
A program that uses semicolons explicitly avoids such problems and is less susceptible to behavior changes (including script errors) caused by inadvertent changes in line terminators and expressions, including those introduced by build tools (e.g. minficication).