【问题标题】:Understanding terminology and notation JavaScript理解术语和符号 JavaScript
【发布时间】:2014-01-08 11:46:42
【问题描述】:

考虑 ECMA-262 的 Sec. 11.2

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

PrimaryExpression 如下

PrimaryExpression :
    this 
    Identifier 
    Literal 
    ArrayLiteral 
    ObjectLiteral 
    ( Expression )

第一个问题是:

( Expression )PrimaryExpression 防御中的含义是什么?

{prop: 'prop'}ObjectLiteral。因此{prop: 'prop'}()CallExpression。我正在尝试使用JSFIDDLE 进行检查,但我有

[20:16:12.347] SyntaxError: syntax error @ http://fiddle.jshell.net/_display/:21

第二个问题: 为什么会出现这个错误?我认为{prop: 'prop'}() 是正确的行,除了错误将是{prop: 'prop'} is not a function

UPD:我使用的是 firefox 25.0.1

【问题讨论】:

  • 我相信,{...}() 在语法上是有效的。在我的 chrome 上,我没有收到语法错误,而是收到“对象不是函数”——这意味着它是有效的。在您的小提琴中,只需将 var x = 添加到您的行中,您将收到相同的错误。
  • @Thrustmaster 有趣。您需要添加该作业吗?
  • @Thrustmaster 非常有趣,感谢您的评论。你能解释一下为什么var x={prop:'prop'}() 在语法上是有效的吗?如果可能,请提供证明/链接。我仍然无法回答我的两个问题。
  • @cstack 这是因为 JS Parser 将其视为代码块而不是对象。 :)

标签: javascript


【解决方案1】:

第一个问题:

( Expression ) 仅表示(Expression,然后是)


第二个问题:

{prop: 'prop'}()

被解析为:

// a block
{
    // syntax error
    prop: 'prop'
}
// syntax error
()

你可以添加括号,然后你会得到预期的错误:

({prop: 'prop'}())

这也有效,因为那里的块无效:

var obj = {prop: 'prop'}
obj()

【讨论】:

    【解决方案2】:

    至于大问题:

    PrimaryExpression 定义中的 ( Expression ) 是什么意思?

    这是一个递归定义,用于在语法中嵌套任意东西。

    JavaScript 语法允许类似

    var o = "Hello" +({stuff:"stuff"}); 
    

    虽然这在语义上不是很有意义,但我们需要能够将任意表达式表达为语言中表达式的一部分。

    语法中的这种递归属性允许任意嵌套。

    让我们通过例子来看看。

    一个更简单的语法可能是描述基本数学的语法。我们想描述一些基本的东西,比如3+5+3/(5+3)

    我们希望允许运算符优先级和任意嵌套 - 这里的定义本身就是递归的。让我们从维基百科看一下:

    <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"
    

    注意这里的&lt;factor&gt; 允许"(" &lt;expression&gt; ")" 以允许我们想要的任意嵌套。

    至于为什么你的{}语法无效:

    {prop: 'prop'} 无效,您在此处开始一个块语句。

    正式 - 你根本不在左侧表达式中,因此第 11.2 节不适用于此处。

    而是你在12 - statement

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

    当它在此处点击 Block - 它看到 12.1 - Block 反过来:

    Block :    
        { StatementListopt }
        StatementList :
        Statement
        StatementList Statement
        Semantics
    

    就语法而言 - 我们在 StatementListBlock 内。

    该语句包括prop: prop。在这里,prop: 被解析为 LabelledStatement,这解释了错误。

    请参阅my answer here,了解它是如何在盘子中实现和包装的。

    【讨论】:

    • 感谢您的回答!但我还有一个问题:您能解释一下({prop: 'prop'})()({prop:'prop'}()) 之间的区别吗?
    • @St.Antario 在语法上它们是不同的,在语义上它们是相同的(语法错误)。这里语法的主要区别在于,在第一个中,我们首先将对象作为表达式求值,然后尝试调用它,而在第二个中,我们尝试在表达式中调用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2011-10-14
    • 1970-01-01
    • 2016-09-18
    • 2022-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多