The =
assignment operator is right-associative, meaning that a chain of assignments is evaluated right to left. That is, the language treats this
x = y = x+2;
as if it were written
x = (y = x+2);
So first y
is assigned the result of the addition (5
), and then x
is assigned the value of that assignment, which is also 5
.
The first example in your question is the same story, but things are a little more complicated:
foo.x = foo = { n: 2 };
The first assignment that's made is to foo
, of that object literal. However, before that point, the language will have determined the reference value of foo.x
, which is a reference to a (not-yet existing) property on the original foo
object. Thus, when the value of the right-hand assignment is made to that property, it does work, but the property is set on the old object, not the new one!
Let's change the example:
var foo = {n: 1}, foo2 = foo;
foo.x = foo = {n: 2};
console.log(foo2.x); // { n: 2 }
That version preserves another reference to the original value of foo
in the variable foo2
. Even though foo
is overwritten in the double assignment, foo2
will continue to refer to the original foo
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…