0

以下は、2 つの代入演算子を含む複合式です。

var a = {n: 1};
var b = a;
a.x = a = {m: 2};
a;    // => {m: 2}
b;    // => {n: 1, x: {m: 2}}

トリッキーな部分は 3 行目です。

a.x = a = {m: 2};

IMHO、代入演算子=は右結合であるため、式のネスト構造は次のとおりです。

a.x = (a = {m: 2});

ただし、 ES5 Annex Dによると、ES5 の評価順序は常に左から右です。

ES5 セクション 11.13.1によると、

プロダクションAssignmentExpression : LeftHandSideExpression = AssignmentExpressionは次のように評価されます。

  1. lrefをLeftHandSideExpressionの評価結果とします
  2. AssignmentExpressionを評価した結果を rref とします
  3. rvalを GetValue( rref )とします。
  4. 次の条件がすべて真の場合、 SyntaxError例外をスローします: ....スペースを節約するために意図的に省略されています
  5. PutValue( lref , rval )。
  6. rvalを返します。

したがって、左から右への評価順序についての私の理解は次のとおりです。

  1. 最初に評価し、その参照をa.x返しますlref1
  2. a = {m: 2}を取得するために評価しrref1ます。これは代入式でもあるため、手順を再度開始します (再帰のように)。

    2.1. 最初に評価し、その参照を a返しますlref2

    2.2. {m: 2}まさにオブジェクト{m: 2}を評価して返すrref2

    2.3. Let rval2= 、オブジェクトもGetValue(rref2)そうですrval2{m: 2}

    2.4. PutValue(lref2, rval2)の代わりにaオブジェクトを再バインドします。{m: 2}{n: 1}

    2.5。return rval2、つまりオブジェクト{m: 2}as rref1(参照型ではなくオブジェクト)

  3. Let rval1= GetValue(rref1)、これはまさにオブジェクトでもあります{m: 2}

  4. PutValue(lref1, rval1)なので、参照するメモリアドレスlref1は になります{m: 2}。そして、b.xまだこのアドレスを参照し、b更新されます.

この手順は ES5 仕様に準拠しており、結果をよく説明しています。

私の質問は次のとおりです。

  1. 上記の評価順序は真か偽か?間違っている場合、別の説明はありますか?

  2. ES5の参照仕様タイプを適切に理解するには? 特定のメモリアドレスを参照するのは単なる中間ポインタですか?

4

1 に答える 1