Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is output for foo.x

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.

like image 979
lxx22 Avatar asked Sep 19 '25 01:09

lxx22


1 Answers

This is the expected behavior. See the specification:

Simple Assignment ( = )

The production AssignmentExpression : LeftHandSideExpression = AssignmentExpression is evaluated as follows:

  1. Let lref be the result of evaluating LeftHandSideExpression.
  2. Let rref be the result of evaluating AssignmentExpression.
  3. Let rval be GetValue(rref).
  4. Throw a SyntaxError exception if (...unimportant)
  5. Call PutValue(lref, rval).
  6. 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);
like image 186
CertainPerformance Avatar answered Sep 20 '25 15:09

CertainPerformance