Consider the following statements:
var foo = {n: 1};
foo.bar = foo = {n: 2};
Can you explain why foo.bar is undefined instead of being foo?
When executing the assignment operator, JS evaluates the left part first. So this
foo.bar = foo = {n: 2};
is interpreted as
evaluate foo.bar. This returns a reference {base: Object {n:1}, property:bar}.
then evaluate the second assignment:
2.1 eval foo. This returns a reference {base:<scope>, property:foo}
2.2. eval {n:2}. This creates a new object.
2.3 put value: <scope>.foo = {n:2}
2.4 return {n:2}
put value to the first reference: {n:1}.bar = {n:2}. This runs fine, but the old object {n:1} is not accessible anymore, since <scope>.foo already refers to the new object
Details: http://ecma-international.org/ecma-262/5.1/#sec-11.13.1
If you make a copy of foo before, you'll see that the leftmost = actually modifies the old object:
var foo = {n:1};
var oldFoo = foo;
foo.bar = foo = {n: 2};
document.write(JSON.stringify(foo) + "<br>")
document.write(JSON.stringify(oldFoo) + "<br>")
So by the time the assignment for foo.bar happens, the reference is "filled in" for foo. which makes it the original object.
Let's expand your code a bit to make it more clear.
var foo1, foo2;
foo1 = foo2 = {n:1};
foo1 === foo2; // true
foo1.bar = foo1 = {n:2}
foo1.bar === foo2; // false
foo1 === foo2; // false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With