美文网首页JavaScript
[JavaScript] function(){}()为什么不合

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

作者: 何幻 | 来源:发表于2016-03-06 10:45 被阅读45次

    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
    

    失败的原因是,
    <u></u>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(){}()为什么不合

        本文链接:https://www.haomeiwen.com/subject/npjnkttx.html