什么';在JavaScript语法中,它是一个有效的左侧表达式吗?

什么';在JavaScript语法中,它是一个有效的左侧表达式吗?,javascript,grammar,ecma262,Javascript,Grammar,Ecma262,好的,我们都知道有效的左侧表达式是什么。有点* 但是,从定义来看,我很困惑: LeftHandSideExpression : NewExpression CallExpression 这只是定义上的一个错误,还是我这里有什么地方出错了?我是说,这不是真的意味着 new Object = 1; // NewExpression AssignmentOperator PrimaryExpression function () { return foo; }() = 1;// Ca

好的,我们都知道有效的左侧表达式是什么。有点*

但是,从定义来看,我很困惑:

LeftHandSideExpression :
    NewExpression
    CallExpression
这只是定义上的一个错误,还是我这里有什么地方出错了?我是说,这不是真的意味着

new Object = 1; // NewExpression AssignmentOperator PrimaryExpression
function () { return foo; }() = 1;// CallExpression AssignmentOperator PrimaryExpression
应该是有效的赋值表达式吗


*根据我的理解,这将更有意义:

LeftHandSideExpression :
    Identifier
    MemberExpression [ Expression ]
    MemberExpression . IdentifierName
    CallExpression [ Expression ]
    CallExpression . IdentifierName

为了简洁地回答您的问题,
LeftHandSideExpression
产品下面的所有内容都是有效的
LeftHandSideExpression


我认为你真正要问的问题是:

什么是有效的
LeftHandSideExpression
和可赋值的

答案是任何解析为
参考的东西,这是规范中定义良好的概念。在你的例子中

new Object = 1;
新对象
是有效的
LeftHandside表达式
,但它不会解析为
引用

(new Object).x = 1;
左侧是一个
MemberExpression。标识名称
根据规范,最后一步是:

返回类型为Reference的值


如果你把它分为2个属性,它就更有意义了。

  • 它是有效的LeftHandside表达式吗
  • 这是有效的参考资料吗 属性1在语法分析阶段确定,属性2在语义分析阶段确定。查看8.7.2 PutValue(V,W)了解更多详细信息

    以下是规范本身的完整解释:

    8.7参考规范类型

    引用类型用于解释delete、typeof和赋值运算符等运算符的行为。例如,赋值的左操作数将生成引用。相反,赋值行为可以完全通过对赋值运算符左侧操作数的语法形式的案例分析来解释,但有一个困难:允许函数调用返回引用。这种可能性完全是为了主机对象而允许的。本规范定义的任何内置ECMAScript函数都不会返回引用,用户定义的函数也不会返回引用。(不使用语法案例分析的另一个原因是,它既冗长又笨拙,会影响规范的许多部分。)


    在看了你的建议之后,我相信它会抛弃某些有效的表达方式(注意:我不宽恕这一点)


    在这种情况下,
    NewExpression
    非常重要

    这是一种可选的JavaScript语法,它只会匹配有效的LeftHandside表达式,即实际可赋值的LeftHandside表达式

    NewExpression :
        PrimaryExpression
        new NewExpressionQualifier Arguments
        new NewExpressionQualifier
    
    NewExpressionQualifier :
        NewExpressionQualifier Qualifier
        NewExpression
    
    CallExpression :
        NewExpression
        CallExpressionQualifier Arguments
    
    CallExpressionQualifier :
        CallExpression
        CallExpressionQualifier Qualifier
    
    LeftHandSideExpression :
        LeftHandSideExpression Qualifier
        CallExpression Qualifier
        Identifier
        ( LeftHandSideExpression )
        ( Expression , LeftHandSideExpression )
    
    Qualifier :
        . IdentifierName
        [ Expression ]
    

    对于关联的new或call表达式选择不明确的每个参数,应将其与可能最近的新表达式关联,否则该表达式将没有相应的参数。我认为这是JavaScript语法中同时存在NewExpression和MemberExpression nonterminal的原因之一。

    如果将函数调用封装在括号中,则第二个示例将起作用:
    (函数(){return window;}())。x=1
    @Daniel:对,我更新了example@user123444555621你的(谦虚的理解)
    LeftHandSideExpression
    的定义缺少分组运算符
    (LeftHandSideExpression)
    。True。我一直认为阶段2在运行时执行,而阶段1在解析时执行。因此,
    if(false){new Object=1;}
    不应该是语法错误,并且在Safari中不起作用。看看Firefox的源代码,我发现:Firefox将此代码视为特例。(有趣的事实:错误代码被称为
    JSMSG_BAD_LEFTSIDE_OF u ASS
    )@Pumbaa80-我认为这样做在动态语言中是有意义的。为什么规范将生产类遗产设置为“扩展”LeftHandSideExpression?不应该是这样吗?我觉得这太复杂了。想象一个类定义,比如类X扩展(新Y)或类X扩展(函数(){})!世界上谁会需要这样的功能性?事实上,firefox甚至将第一种情况视为无效。根据您对
    LeftHandSideExpression
    的定义,我得出结论认为
    (a=1,b)
    将是一种可分配的
    LeftHandSideExpression
    。但是,在赋值
    (a=1,b)=2
    中使用它会导致
    未捕获引用错误:赋值
    中的左侧无效。逗号运算符不是左侧表达式,因为它不返回引用(4.返回GetValue(rref))。但是,它可能包含一个简单的赋值表达式作为右操作数<代码>a=1,b=2
    可以分组为
    (a=1),
    ,但是
    (a=1,b)=2
    将导致
    GetValue(b)=2
    NewExpression :
        PrimaryExpression
        new NewExpressionQualifier Arguments
        new NewExpressionQualifier
    
    NewExpressionQualifier :
        NewExpressionQualifier Qualifier
        NewExpression
    
    CallExpression :
        NewExpression
        CallExpressionQualifier Arguments
    
    CallExpressionQualifier :
        CallExpression
        CallExpressionQualifier Qualifier
    
    LeftHandSideExpression :
        LeftHandSideExpression Qualifier
        CallExpression Qualifier
        Identifier
        ( LeftHandSideExpression )
        ( Expression , LeftHandSideExpression )
    
    Qualifier :
        . IdentifierName
        [ Expression ]