var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
what is output for foo.x. My thought is evaluation from right to left so it is equal to
foo = {n:2};
foo.x = foo
so it will be
{
n: 1
x: {n: 2}
}
But it is not, it is undefined? I am get confused, looking for an explanation.
This is the expected behavior. See the specification:
Simple Assignment ( = )
The production AssignmentExpression : LeftHandSideExpression = AssignmentExpression is evaluated as follows:
- Let lref be the result of evaluating LeftHandSideExpression.
- Let rref be the result of evaluating AssignmentExpression.
- Let rval be GetValue(rref).
- Throw a SyntaxError exception if (...unimportant)
- Call PutValue(lref, rval).
- Return rval.
In short, when the interpreter sees x = <expression>
, or x.prop = <expression>
, it first identifies what to assign to - that is, the LeftHandSideExpression. Then, after evaluating the right-hand side (the AssignmentExpression) to a value, it assigns the value to what was initially identified as the LeftHandSideExpression. So, with
foo.x = foo = {n: 2};
foo.x
mutates the original foo
object, not the reassigned foo = {n: 2}
object, so after the foo.x = foo = {n: 2}
line, foo
refers to the new {n: 2}
, which is never mutated.
You can see how bar
, which references the same object in memory as the original foo
, gets mutated:
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
console.log(bar);
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