1
var foo = {n: 1};
foo.x = foo = {a: 2};
console.log(foo.x);
// Output -- undefined 

var a = 1;
c = b = a;
console.log(a,b,c);
// Output -- 1, 1, 1

Could you please explain why first example returns undefined where as second returns 1,1,1?

5
  • 1
    foo is being reassigned. Commented Apr 1, 2017 at 8:58
  • 1
    I guess the reason for this is that Objects are used as reference. So in foo.x=foo={a:2};, foo.x is assigned something, but then you are changing reference of foo itself. So any value set before is lost Commented Apr 1, 2017 at 8:58
  • Code works like reading Left to Right, So, foo.x is {a:2}, but next foo becomes {a:2}, so it has no x property. Commented Apr 1, 2017 at 9:02
  • @Rajesh yes Rajesh I thing you are right it was initialised with foo.x = foo first but after that again we are changing foo reference where we don't have x property that's why it returns undefined you are right thanks brother now I got it... Commented Apr 1, 2017 at 9:02
  • True @Rajesh, Objects are not Primitive, therefore assignment to another variable is a reference to the Object itself, but reassigning a variable will overwrite it anyways. Commented Apr 1, 2017 at 9:09

3 Answers 3

2

That happens because expressions in javascript are evaluated left to right.

So in this expression:

foo.x=foo={a:2}

first the foo is dereferenced and a property x is set to be the target of the right operand foo={a:2} result.

Then, while the right operand is evaluated, the foo value is reassigned, so a reference to the previous instance of the object is lost.

To demonstrate it we may simply create another variable to keep it:

var foo = {n:1};
var bar = foo;
foo.x=foo={a:2};
console.log(foo, bar);

Sign up to request clarification or add additional context in comments.

8 Comments

You beat me by 17 secs. :-)
@Rajesh yep, and even variable names matched, sorry ;-)
Na. I'm glad to delete my answer. Your explanation is way better. :-)
But still I am having confusion over here if I print bar.x it print {a:2} and foo.x is undefined why is this then if it points to same obj reference then it should print the same value as bar.x
@ManojSawant see the change, are the results more clear now? "if it points to same obj reference" --- it does not. After the foo={a:2} assignment it is a completely new object.
|
1

That's because the {a:2} object is actually being assigned to the {n:1}.x property! Not to {a:2}. There is no "x" property in it.

What we have here is:

var foo = {n:1};
foo.x = foo = {a:2}; // equals:...
{n:1}.x = {a:2};
/* note that foo.x is actually referring to {n:1} object! */
foo = {a:2}; // ==>
/* while foo is being pointed to a different object
   which is now the {a:2} object!
   wherefore ...*/
{a:2}.x   // is normally undefined i.e.: never set!

However:

{n:1}.x // has been successfully assigned with:
>> {a:2} object. 

But because you are loosing a reference to the object {n:1}, and have no other way to examine it. In order to verify and prove that it is {n:1} who is actually receiving the property "x", we'll have to give it a backup reference before we overwrite the foo variable in order to be able to return it.

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

console.log(foo.x); 
console.log(bak.x);

>> undefined
>> {a:2}.

Comments

0
foo.x = foo = {a: 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.

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 and hence an undefined value

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.