Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a semicolon required at end of line?

Why does this work:

a = []
a.push(['test']);
(function() {alert('poop')})()

But this gives the error "number is not a function":

a = []
a.push(['test'])
(function() {alert('poop')})()

The only difference is the semicolon at the end of line 2. I've been writing JavaScript for a long time now. I know about automatic semicolon insertion, but I can't figure out what would be causing this error.

like image 794
Johntron Avatar asked Mar 02 '11 18:03

Johntron


2 Answers

Take a look at this example of chained function calls.

a.push(['test'])(function() {alert('poop')})()

Look familiar? This is how the compiler/interpreter views your code.

Detail

Here is a portion of the grammar used to describe call expressions.

CallExpression : 
	MemberExpression Arguments 
	CallExpression Arguments 
	CallExpression [ Expression ] 
	CallExpression . IdentifierName 

Essentially each group (...) is considered as Arguments to the original MemberExpression a.push.

a.push (['test'])                // MemberExpression Arguments 
(function() {alert('poop')})     // Arguments  
()                               // Arguments 

Or more formally

CallExpression(
    CallExpression(  
        CallExpression(
            MemberExpression( a.push ),
            Arguments( (['test']) )
        ),
        Arguments( (function() {alert('poop')}) )
    ),
    Arguments( () )
)
like image 92
ChaosPandion Avatar answered Oct 20 '22 14:10

ChaosPandion


I'm not a Javascript expert (or even a newbie :), but if you combine the second and third lines, it still looks syntactically valid:

a.push(['test'])(function() {alert('poop')})()

That's trying to treat the result of a.push(['test']) as a function, passing a function into it... and then calling the result as a function as well.

I suspect that the semi-colon is required if the two statements can be syntactically combined into a single statement, but that's not what you want.

like image 44
Jon Skeet Avatar answered Oct 20 '22 14:10

Jon Skeet