以下は、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は次のように評価されます。
- lrefをLeftHandSideExpressionの評価結果とします。
- AssignmentExpressionを評価した結果を rref とします。
- rvalを GetValue( rref )とします。
- 次の条件がすべて真の場合、 SyntaxError例外をスローします: ....スペースを節約するために意図的に省略されています
- PutValue( lref , rval )。
- rvalを返します。
したがって、左から右への評価順序についての私の理解は次のとおりです。
- 最初に評価し、その参照を
a.x
返しますlref1
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}
asrref1
(参照型ではなくオブジェクト)Let
rval1
=GetValue(rref1)
、これはまさにオブジェクトでもあります{m: 2}
PutValue(lref1, rval1)
なので、参照するメモリアドレスlref1
は になります{m: 2}
。そして、b.x
まだこのアドレスを参照し、b
更新されます.
この手順は ES5 仕様に準拠しており、結果をよく説明しています。
私の質問は次のとおりです。
上記の評価順序は真か偽か?間違っている場合、別の説明はありますか?
ES5の参照仕様タイプを適切に理解するには? 特定のメモリアドレスを参照するのは単なる中間ポインタですか?