17

さて、私たちは皆、有効な左辺の式が何であるかを知っています。すこし。*

しかし、 ECMA-Script standardの定義を見て、私は非常に混乱しています:

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

4

2 に答える 2

14

あなたの質問に簡潔に答えるために、LeftHandSideExpressionプロダクションの下にあるものはすべて有効ですLeftHandSideExpression


あなたが本当に求めている質問は次のとおりだと思います。

有効LeftHandSideExpressionで割り当て可能とは何ですか?

それに対する答えはReference、仕様で明確に定義された概念であるに解決されるものです。あなたの例では

new Object = 1;

new Object有効ですLeftHandSideExpressionが、 に解決されませんReference

(new Object).x = 1;

左側はMemberExpression . IdentifierName、仕様によると最終ステップは次のとおりです。

Reference 型の値を返します ...


それを 2 つの別個のプロパティと見なすと、はるかに理にかなっています。

  1. 有効な LeftHandSideExpression ですか?
  2. それは有効な参照ですか?

プロパティ 1 は構文解析フェーズで決定され、プロパティ 2 は意味解析フェーズで決定されます。詳細については、8.7.2 PutValue (V, W)を参照してください。

仕様自体の完全な説明は次のとおりです。

8.7 参照仕様タイプ

Reference 型は、delete、typeof、および代入演算子などの演算子の動作を説明するために使用されます。たとえば、代入の左側のオペランドは参照を生成すると予想されます。代わりに、代入演算子の左側のオペランドの構文形式に関するケース分析の観点から代入の動作を完全に説明できますが、1 つの問題があります。関数呼び出しは参照を返すことが許可されています。この可能性は、純粋にホスト オブジェクトのために認められています。この仕様で定義されている組み込みの ECMAScript 関数は参照を返しません。また、ユーザー定義関数が参照を返すための規定もありません。(構文のケース分析を使用しないもう 1 つの理由は、長くてぎこちなく、仕様の多くの部分に影響を与えることです。)


あなたの提案を見た後、それは特定の有効な表現を捨てると思います(注:私はこれを容認しません。)

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

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

NewExpression重要なケースです

于 2010-09-14T14:46:30.400 に答える
2

これは、有効な LeftHandSideExpressions、つまり実際に割り当て可能な LeftHandSideExpressions のみに一致する代替 JavaScript 文法です。

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 式の選択があいまいな各 Arguments は、対応する Argument を持たない可能性のある最も近い new 式に関連付けられます。これが、JavaScript 文法に NewExpression と MemberExpression の両方の非終端記号がある理由の 1 つだと思います。

于 2017-09-14T15:18:46.110 に答える