Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript code trick: What's the value of foo.x

I found this problem in a GitHub front-end interview questions collection:

var foo = {n: 1}; var bar = foo; foo.x = foo = {n: 2}; 

Question: What is the value of foo.x?

The answer is undefined.

I've done some research and what I understand this problem is (correct me if I'm wrong):

  • var foo = {n: 1}; declares an object foo which has property n equal to 1.
  • var bar = foo; declares an object bar which refers to the same object as foo.
  • foo.x = foo = {n: 2}; which I believe is equal to foo.x = (foo = {n: 2});
  • And then I got foo.x equals to undefined. However, the value of bar.x is the object {n:2}.

If bar and foo refer to same object, why did bar.x get a value while foo.x is undefined? What is really happening in foo.x = foo = {n: 2};?

like image 297
AndyHu Avatar asked Sep 02 '15 00:09

AndyHu


2 Answers

foo.x = foo = {n: 2}; 

determines that foo.x refers to a property x of the {n: 1} object, assigns {n: 2} to foo, and assigns the new value of foo{n: 2} – to the property x of the {n: 1} object.

The important thing is that the foo that foo.x refers to is determined before foo changes.

See section 11.13.1 of the ES5 spec:

  1. Let lref be the result of evaluating LeftHandSideExpression.

  2. Let rref be the result of evaluating AssignmentExpression.

The assignment operator associates right to left, so you get:

foo.x = (foo = {n: 2}) 

The left hand side is evaluated before the right hand side.

like image 183
Ry- Avatar answered Sep 20 '22 11:09

Ry-


foo.x = foo = {n: 2}; 

Here foo refers to {n:1} object before assignment i.e. before the statement is executed.

The statement can be re-written as foo.x = (foo = {n:2});

In object terms the above statement can be re-written as {n:1}.x = ( {n:1} = {n:2} );

Since assignment happens from right to left only. So here we just have to keep a check that foo is referring to which object before execution starts.

On solving the R.H.S: foo = {n:2}; Now foo is referring to {n:2};

Coming back on the problem we are left with:

foo.x = foo; 

Now foo.x on L.H.S is still {n:1}.x whereas foo on R.H.S is {n:2}.

So after this statement gets executed {n:1} will become { n:1, x:{n:2} } with bar still referring to it. Where as foo will now be referring to {n:2}.

So on execution foo.x gives undefined as there is only 1 value in foo which is {n:2}.

But if you will try executing bar.x it will give {n:2}. Or if you will just execute bar the result will be

Object {n: 1, x: Object} 
like image 23
Shardul Singh Rana Avatar answered Sep 23 '22 11:09

Shardul Singh Rana