In this post, Multiple left-hand assignment with JavaScript, @Crescent Fresh says JavsScript left-hand assignment is right associative. But the following code seems to me it breaks right associativeness:
var a = {n: 1};
a.x = a = {n: 2};
console.log(a.x);// undefined
Can anyone explain why a.x
is undefined?
Edit:The snippet above is to test "right associativeness", in real world please do not write similar code.
It is right associative. It's simply that the identifier a
is bound to a reference before the statement executes.
We can witness this with the following:
var a, b;
a = b = { n: 1 };
a.x = a = {n: 2}; // a.x refers to the x property of the value a references
// before this statement executes
console.log(a); // {n: 2}
console.log(b); // {n: 1, x: {n: 2}}
If =
were left associative, b.x
would be a circular reference back to b
after the third line executes, but it isn't.
Can anyone explain why a.x is undefined?
Yes, this is what happens when the line a.x = a = {n: 2}
executes:
{n: 2}
is assigned to the variable a
{n: 2}
is assigned to the x
property of the object that a
referred to before the statement started executing.Nothing is assigned to the x
property of a
's new value. That's why a.x
is undefined
.
tl;dr — JS works out where to put the value before working out what that value is, and a side effect of working out what that value is changes the value of a
.
See the spec for simple assignment.
Step 1 is "Let lref be the result of evaluating LeftHandSideExpression."
Step 2 is "Let rref be the result of evaluating AssignmentExpression."
So the first thing that happens is that a property x
is created on the object stored in a
(where n is 1).
Then the right hand side is evaluated (which ends up overwriting a
with a new object where n is 2).
Then the result of that expression (that object where n is 2) is assigned to x
on the original object (where n is 1).
You can see this in effect with:
"use strict";
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a);
console.log(b);
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