JS連続イコールの割当問題
1828 ワード
最近GitHubで面白い問題を発見しました.
ECMAScript仕様によると、 Let lref be the relt of evaluating LeftHandSideExpressition. ReturnIfAbrappt. Let rref be the result of evaluating Asignments Expressition. Let rval be GetValue.[…] 大体の意味は、A=Bのような表現については、まずA式を計算し、lrefを得て、計算式Bを計算し、Bの値rvalを得て、rvalをlrefに割り当てた変数をrvalに返します.
JSの割当表現は右結合なので、foo.x=foo={n:2}はfoo.x=(foo={n:2}に等しいです.
計算順序によって、は、括弧内の値を計算し、foo.xに割り当てます. はfoo.x={n:2}を得て、同時にbar.x={n:2}を得て、左の最初の等号の計算は終わります. は次に、括弧内の表現、すなわちfoo={n:2}を計算する. fooは新しいオブジェクトに与えられ、元のオブジェクトの参照ではなく、{n:2}を指していますので、foo.xはundefinedを得ていますが、barは元のオブジェクトを指していますので、bar値は変わりません. このセグメントのコードは以下のコードと同じです.
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
console.log(foo.x); // undefined
console.log(bar); // Object {n: 1, x: {n:2}}
運転結果はfoo.xの値がundefinedであることを示しています.分析過程は以下の通りです.ECMAScript仕様によると、
JSの割当表現は右結合なので、foo.x=foo={n:2}はfoo.x=(foo={n:2}に等しいです.
計算順序によって、
var foo = {n: 1};
var bar = foo;
var foo1 = {n: 2};
foo.x = foo1;
foo = foo1;
console.log(foo.x,bar);