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?
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);
foo={a:2} assignment it is a completely new object.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}.
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
foois being reassigned.foo.x=foo={a:2};,foo.xis assigned something, but then you are changing reference offooitself. So any value set before is lostfoo.xis{a:2}, but nextfoobecomes{a:2}, so it has noxproperty.@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.