Reputation: 27385
Consider Sec. 11.2 of ECMA-262.
Syntax
MemberExpression :
PrimaryExpression
FunctionExpression
MemberExpression [ Expression ]
MemberExpression . IdentifierName
new MemberExpression Arguments
NewExpression :
MemberExpression
new NewExpression
CallExpression :
MemberExpression Arguments
CallExpression Arguments
CallExpression [ Expression ]
CallExpression . IdentifierName
Arguments :
( )
( ArgumentList )
ArgumentList :
AssignmentExpression
ArgumentList , AssignmentExpression
LeftHandSideExpression :
NewExpression
CallExpression
The PrimaryExpression is the following
PrimaryExpression :
this
Identifier
Literal
ArrayLiteral
ObjectLiteral
( Expression )
The first question is:
What ( Expression )
does mean in the PrimaryExpression
defenition?
The {prop: 'prop'}
is ObjectLiteral
. Thus {prop: 'prop'}()
is CallExpression
. I'm trying to check this with JSFIDDLE but I have
[20:16:12.347] SyntaxError: syntax error @ http://fiddle.jshell.net/_display/:21
The second question:
Why this error was caused? I think that {prop: 'prop'}()
is correct line and I'm excepted that the error will be kind of {prop: 'prop'} is not a function
.
UPD: I'm using firefox 25.0.1
Upvotes: 4
Views: 263
Reputation: 276306
What ( Expression ) does mean in the PrimaryExpression defenition?
It's a recursive definition, used for nesting arbitrary things in the grammar.
JavaScript grammar allows for things like
var o = "Hello" +({stuff:"stuff"});
Although this is not very meaningful semantically, we need to be able to express an arbitrary expression as a part of an expression in the language.
This recursive property in the grammar is what allows arbitrary nesting.
A much simpler grammar might be grammar describing basic math. We want to describe something basic like 3+5+3/(5+3)
.
We want to allow operator precedence and arbitrary nesting - the definition here is itself recursive. Let's see this from Wikipedia:
<expression> ::= <term> | <expression> "+" <term>
<term> ::= <factor> | <term> "*" <factor>
<factor> ::= <constant> | <variable> | "(" <expression> ")"
<variable> ::= "x" | "y" | "z"
<constant> ::= <digit> | <digit> <constant>
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
Note how <factor>
here allows for an "(" <expression> ")"
in it in order to allow the arbitrary nesting we want.
{}
syntax is invalid:{prop: 'prop'}
is not valid, you're starting a block statement here.
Formally - you're not in a left hand side expression at all, so section 11.2 does not apply here.
Rather you're in a 12 - statement:
Syntax
Statement :
Block
VariableStatement
EmptyStatement
ExpressionStatement
IfStatement
IterationStatement
ContinueStatement
BreakStatement
ReturnStatement
WithStatement
LabelledStatement
SwitchStatement
ThrowStatement
TryStatement
DebuggerStatement
When it hits Block
here - it sees 12.1 - Block which in turn does:
Block :
{ StatementListopt }
StatementList :
Statement
StatementList Statement
Semantics
So as far as the grammar is concerned - we're inside a StatementList
inside a Block
.
That statement includes prop: prop
. Here, the prop:
gets parsed as a LabelledStatement
which explains the error.
See my answer here for how it's implemented in plates and wrapping it.
Upvotes: 1
Reputation: 59273
First question:
( Expression )
simply means a (
, an Expression
, and then a )
.
Second question:
{prop: 'prop'}()
Is being parsed as:
// a block
{
// syntax error
prop: 'prop'
}
// syntax error
()
You could add parens, and then you would get the expected error:
({prop: 'prop'}())
This also works since a block is not valid there:
var obj = {prop: 'prop'}
obj()
Upvotes: 2