JavaScript 语法中有效的左侧表达式是什么?

发布于 2024-09-19 09:51:58 字数 756 浏览 8 评论 0原文

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

但是,看看ECMA-Script 标准的定义,我很困惑:

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

Okay, we all know what the valid left-hand-side expressions are. Kind of.*

But, looking at the definition from the ECMA-Script standard, I'm very confused:

LeftHandSideExpression :
    NewExpression
    CallExpression

Is that just an error in the definition, or am I getting something wrong here? I mean, doesn't that actually mean that

new Object = 1; // NewExpression AssignmentOperator PrimaryExpression
function () { return foo; }() = 1;// CallExpression AssignmentOperator PrimaryExpression

are supposed to be valid assignment expressions?


* From my humble understanding, this would make much more sense:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

¢蛋碎的人ぎ生 2024-09-26 09:52:36

这是另一种 JavaScript 语法,它仅匹配有效的 LeftHandSideExpressions,即实际可赋值的 LeftHandSideExpressions。

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 ]

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

This is an alternative JavaScript grammar which only will match valid LeftHandSideExpressions, that is, LeftHandSideExpressions that are actually assignable.

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 ]

Each Arguments for which the choice of associated new or call expression is ambiguous shall be associated with the nearest possible new expression that would otherwise have no corresponding Arguments. I think this is one of the reasons why there is both a NewExpression and a MemberExpression nonterminal in the JavaScript grammar.

凝望流年 2024-09-26 09:52:27

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


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

什么是有效且可赋值的 LeftHandSideExpression

答案是任何解析为Reference 的内容,这是规范中定义明确的概念。在您的示例中,

new Object = 1;

new Object 是有效的LeftHandSideExpression,但它不会解析为Reference

(new Object).x = 1;

左侧是一个 MemberExpression 。 IdentifierName 根据规范,最后一步是:

返回引用类型的值...


如果您将其视为 2 个独立的属性,则更有意义。

  1. 它是有效的 LeftHandSideExpression 吗?
  2. 这是一个有效的参考吗?

属性1在句法分析阶段确定,属性2在语义分析阶段确定。查看8.7.2 PutValue (V, W)了解更多详细信息。

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

8.7 引用规范类型

引用类型用于解释删除、typeof 和赋值运算符等运算符的行为。例如,赋值的左侧操作数预计会产生引用。相反,赋值行为可以完全根据赋值运算符左侧操作数的语法形式的案例分析来解释,但有一个困难:允许函数调用返回引用。这种可能性纯粹是为了宿主对象而被承认的。本规范定义的内置 ECMAScript 函数没有返回引用,并且没有规定用户定义的函数可以返回引用。 (不使用语法案例分析的另一个原因是它会冗长且尴尬,影响规范的许多部分。)


在查看了您的建议后,我相信它会抛弃某些有效的表达式(注意:我不要容忍这种行为。)

function OuterObj() {
    this.Name = "Outer";
    this.InnerObj = function() {
        this.Name = "Inner";
    }
}

var obj; (obj = new new OuterObj().InnerObj).Name = "Assigned";

在这种情况下,NewExpression 很重要

To concisely answer your question, everything beneath the LeftHandSideExpression production is a valid LeftHandSideExpression.


I think the question you are really asking is:

What is a valid LeftHandSideExpression and also assignable?

The answer to that is anything that resolves to a Reference which is a well defined concept in the specification. In your example

new Object = 1;

The new Object is a valid LeftHandSideExpression but it does not resolve to a Reference.

(new Object).x = 1;

The left hand side is a MemberExpression . IdentifierName which according to the spec the final step is:

Return a value of type Reference ...


If you consider it 2 separate properties it makes a lot more sense.

  1. Is it a valid LeftHandSideExpression?
  2. Is it a valid reference?

Property 1 is determined in the syntactical analysis phase and property 2 is determined in the semantic analysis phase. Check out 8.7.2 PutValue (V, W) for more details.

Here is a full explanation in the specification itself:

8.7 The Reference Specification Type

The Reference type is used to explain the behaviour of such operators as delete, typeof, and the assignment operators. For example, the left-hand operand of an assignment is expected to produce a reference. The behaviour of assignment could, instead, be explained entirely in terms of a case analysis on the syntactic form of the left-hand operand of an assignment operator, but for one difficulty: function calls are permitted to return references. This possibility is admitted purely for the sake of host objects. No built-in ECMAScript function defined by this specification returns a reference and there is no provision for a user-defined function to return a reference. (Another reason not to use a syntactic case analysis is that it would be lengthy and awkward, affecting many parts of the specification.)


After taking a look at your suggestion I believe it would throw off certain valid expressions (Note: I don't condone this.)

function OuterObj() {
    this.Name = "Outer";
    this.InnerObj = function() {
        this.Name = "Inner";
    }
}

var obj; (obj = new new OuterObj().InnerObj).Name = "Assigned";

This is a case where NewExpression is important

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文