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