[JavaScript] function(){}()为什么不合法

ES3 P63

ExpressionStatement :
[lookahead ∉ {{, function}] Expression ;

Note that an ExpressionStatement cannot start with an opening curly brace because that might make itambiguous with a Block. Also, an ExpressionStatement cannot start with the function keyword becausethat might make it ambiguous with a FunctionDeclaration.


上下文无关文法《ECMA-262, 3rd edition, December 1999》

Program :
    SourceElements

SouceElements :
    SouceElement
    SouceElements SourceElement

SouceElement :
    Statement
    FunctionDeclaration

Statement :
    Block
    VariableStatement
    EmptyStatement
    ExpressionStatement
    IfStatement
    IterationStatement
    ContinueStatement
    BreakStatement
    ReturnStatement
    WithStatement
    LabelledStatement
    SwitchStatement
    ThrowStatement
    TryStatement

ExpressionStatement :
    [lookahead ∉ {{, function}] Expression ;

FunctionDeclaration :
    function Identifier ( FormalParameterList[opt] ) { FunctionBody }

这几个产生式表明了以Program为根的语法树结构。


(1)首先,“function(){}()”无法归约为CallExpression

CallExpression 
<- LeftHandSideExpression 
<- PostfixExpression 
<- UnaryExpression 
<- MultiplicativeExpression 
<- AdditiveExpression 
<- ShiftExpression 
<- RelationalExpression 
<- EqualityExpression 
<- BitwiseANDExpression 
<- BitwiseXORExpression 
<- BitwiseORExpression 
<- LogicalANDExpression 
<- LogicalORExpression 
<- ConditionalExpression 
<- AssignmentExpression 
<- Expression
[失败了] <- ExpressionStatement 
<- Statement 
<- SourceElement 
<- SourceElements 
<- Program

失败的原因是,
Expression要想归约为ExpressionStatement,就不能以左大括号“{”或“function”开头。

(2)那么,我们只能认为“function(){}()”是由两部分构成的了。

program
-> SourceElements
-> SourceElements SourceElement
-> SourceElement SourceElement

把“funtion(){}”和“()”都分别向SourceElement归约。
然而,这又不行。

(3)“funtion(){}”无法归约为SourceElement
因为,无论是先归约为Statement,还先归约为FunctionDeclaration都不行。
归约为Statement要求不能以function开头,(与上面的失败原因相同)
归约为FunctionDeclaration要求必须指定函数名。

(4)然而,我们又没有其他归约方法了,只能失败了。


而加上符号以后,
例如“!function(){}()”,并不是以“function开头”的,
所以通过了ExpressionExpressionStatement的归约。

!function(){}()
<- ! function Identifieropt ( FormalParameterListopt ) { FunctionBody } Arguments
<- ! FunctionExpression Arguments
<- ! MemberExpression Arguments
<- ! CallExpression
<- ! LeftHandSideExpression
<- ! PostfixExpression
<- ! UnaryExpression
<- UnaryExpression
<- MultiplicativeExpression
<- AdditiveExpression
<- ShiftExpression
<- RelationalExpression
<- EqualityExpression
<- BitwiseANDExpression
<- BitwiseXORExpression
<- BitwiseORExpression
<- LogicalANDExpression
<- LogicalORExpression
<- ConditionalExpression
<- AssignmentExpression
<- Expression
<- ExpressionStatement
<- Statement
<- SourceElement
<- SourceElements
<- Program

同理可以推导(function(){}())(function(){})()


值得指出的是,
function(){}()”就算指定了函数名,也不行。
因为后面的“()”也不能归约为SourceElement

而“function f(){}(1)”就是合法的,
function f(){}”归约为FunctionDeclaration
而“(1)”可以归约为Expression,视为括号运算符,或称为分组运算符。

(Expression) 
<- PrimaryExpression
<- MemberExpression
<- NewExpression
<- LeftHandSideExpression
<- PostfixExpression
<- UnaryExpression
<- MultiplicativeExpression
<- AdditiveExpression
<- ShiftExpression
<- RelationalExpression
<- EqualityExpression
<- BitwiseANDExpression
<- BitwiseXORExpression
<- BitwiseORExpression
<- LogicalANDExpression
<- LogicalORExpression
<- ConditionalExpression
<- AssignmentExpression
<- Expression

示例1:(function(){})()

( function Identifieropt ( FormalParameterListopt ) { FunctionBody } ) Arguments
( FunctionExpression ) Arguments
(MemberExpression ) Arguments
(NewExpression ) Arguments
( LeftHandSideExpression ) Arguments
( PostfixExpression ) Arguments
( UnaryExpression ) Arguments
( MultiplicativeExpression ) Arguments
( AdditiveExpression ) Arguments
( ShiftExpression ) Arguments
( RelationalExpression ) Arguments
( EqualityExpression ) Arguments
( BitwiseANDExpression ) Arguments
( BitwiseXORExpression ) Arguments
( BitwiseORExpression ) Arguments
( LogicalANDExpression ) Arguments
( LogicalORExpression ) Arguments
( ConditionalExpression ) Arguments
( AssignmentExpression ) Arguments
( Expression ) Arguments
PrimaryExpression Arguments
MemberExpression Arguments
CallExpression
LeftHandSideExpression
PostfixExpression
UnaryExpression
MultiplicativeExpression
AdditiveExpression
ShiftExpression
RelationalExpression
EqualityExpression
BitwiseANDExpression
BitwiseXORExpression
BitwiseORExpression
LogicalANDExpression
LogicalORExpression
ConditionalExpression
AssignmentExpression
Expression
ExpressionStatement
Statement
SourceElement
SourceElements
Program

示例2:(function(){}())

( function Identifieropt ( FormalParameterListopt ) { FunctionBody }Arguments )
( FunctionExpressionArguments )
( MemberExpression Arguments )
( CallExpression )
( LeftHandSideExpression )
( PostfixExpression )
( UnaryExpression )
( MultiplicativeExpression )
( AdditiveExpression )
( ShiftExpression )
( RelationalExpression )
( EqualityExpression )
( BitwiseANDExpression )
( BitwiseXORExpression )
( BitwiseORExpression )
( LogicalANDExpression )
( LogicalORExpression )
( ConditionalExpression )
( AssignmentExpression )
( Expression )
PrimaryExpression
MemberExpression
NewExpression
LeftHandSideExpression
PostfixExpression
UnaryExpression
MultiplicativeExpression
AdditiveExpression
ShiftExpression
RelationalExpression
EqualityExpression
BitwiseANDExpression
BitwiseXORExpression
BitwiseORExpression
LogicalANDExpression
LogicalORExpression
ConditionalExpression
AssignmentExpression
Expression
ExpressionStatement
Statement
SourceElement
SourceElements
Program

示例3:!function(){}()

! function Identifieropt( FormalParameterListopt) { FunctionBody }Arguments
! FunctionExpressionArguments
! MemberExpression Arguments
! CallExpression
! LeftHandSideExpression
! PostfixExpression
! UnaryExpression
UnaryExpression
MultiplicativeExpression
AdditiveExpression
ShiftExpression
RelationalExpression
EqualityExpression
BitwiseANDExpression
BitwiseXORExpression
BitwiseORExpression
LogicalANDExpression
LogicalORExpression
ConditionalExpression
AssignmentExpression
Expression
ExpressionStatement
Statement
SourceElement
SourceElements
Program

示例4:function(){}()

functionIdentifier( FormalParameterListopt) { FunctionBody } SourceElement
FunctionDeclarationSourceElement
SourceElement SourceElement
SourceElements  SourceElement
SourceElements
Program

你可能感兴趣的:([JavaScript] function(){}()为什么不合法)