There is a good explanation at http://inimino.org/~inimino/blog/javascript_semicolons. Quoting from it:
3. When a "restricted production" is encountered and contains a line terminator in a place where the grammar contains the annotation "[no LineTerminator here]", then a semicolon is inserted.
[...]
Restricted productions are those in which a line break cannot appear in a particular position, so if a line break appears there, it will prevent the program from parsing in that way, though it may still parse another way.
There are five restricted productions in the grammar, they are the postfix operators ++
and --
, continue statements, break statements, return statements, and throw statements.
[...]
Note that return statements can contain linebreaks within the expression, just not between the return
token and the start of the expression.
In other words, return ...
is a specific construct wherein, if you put a line-break after the return
, JavaScript will insert a semicolon. There are several other such constructs as well; but aside from these, JavaScript will only ever insert a semicolon if there's no way to make sense of your code without one.