1

Why is a.y undefined after I change the reference of a in the function?

var a = { x : 1 };
a = { y : 2 };
function _change(b) {
    b = { y : 3 };
    return b;
}

_change(a);
document.write(a.y);   // undefined
document.write(a.x);   //1

And the below code behaves differently

var a = {x:1};
var b={y:1};
b=a;
a.x //undefined
a.y //1

Why?

royhowie
  • 11,075
  • 14
  • 50
  • 67
user2713706
  • 147
  • 6
  • 1
    `a.x` is `undefined` here, not `a.y`. – BatScream Jan 09 '15 at 07:38
  • 1
    Neither of the blocks of code that you show would give the outputs that your comments say they would. (As you can see [here](http://jsfiddle.net/j2g68rf9/) for the first block.) – nnnnnn Jan 09 '15 at 07:42

3 Answers3

1

Because you're totally changing the a object {x:1} with {y:2} so there's no x property in a object.

What I think is you need to use like this:

var a = {x:1};
a.y = 2;//assign y = 2 in a oject.

So, do the same manner in your change function.

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231
1

First Block

This is what I get by running the code line by line:

var a = {x:1};  // <-- sets a to the object {x:1}
a = {y:2}; // <-- sets a to the object {y:2}, so it no longer has a.x = 1

function _change(b)
{
    b= { y:3};
    return b;
}

_change(a); // <-- this doesn't change a, it returns {y: 3} but it is not used

document.write(a.y); // 2 actually
document.write(a.x); // undefined

Let's try to understand it...

var a = {x:1};

There you declare the variable a, you create an object {x:1}, and set a to that object.

a = {y:2};

There you create a new object {y:2} and set a to it. So a no longer has the first object.

So... when you ask for a.y it has 2, and when you ask for a.x it is undefined because the object {y:2} doesn't have x. Remember that you replaced the object of the variable a from being {x:1} to {y:2}.


Instead you can add fields on the fly, like this:

var a = {x:1};  // <-- sets a to the object {x:1}
a.y = 2; // <-- Add a field y to the object of the variable a, it has the value 2

function _change(b)
{
    b.y = 3; // <-- actually modify the object, now the field y has value 3
    return b;
}

_change(a);

document.write(a.y); // 3
document.write(a.x); // 1

Second Block

Again, I get a different result than you... I wonder where are you running your code.

var a = {x:1}; // <-- sets a to the object {x:1}
var b={y:1}; // <-- sets b to the object {y:1}
b=a; // <-- now sets b to the object {x:1} - nobody has {y:1} anymore
document.write(a.x); // 1 actually
document.write(a.y); // undefined

Ok, so when you say b=a you are making the variable b to point to the same object as the variable a. By doing so, the variable b no longer points to the object {x:1}... which is irrelevant because you are not using the variable b anyway.

The variable a had {x:1} all along, and you can see it doesn't have any field y defined.


It seems to be that you believe that assigning an object somehow fuses the objects, resulting in both sides having a combination of the fields... if you intend to do that, you may be interested in How can I merge properties of two JavaScript objects dynamically?.

Community
  • 1
  • 1
Theraot
  • 31,890
  • 5
  • 57
  • 86
0

You need to break this down and understand the variables in different lexical scopes.

a in the global lexical scope:

var a = {x:1};
a = {y:2};

The above initialization would resolve to:

a = {y:2};

//hence at this global lexical scope 
//`lexicalscope = {"a":{y:2}};`

Now, let us see the variables inside the lexical scope of the function:

function _change(b){
       // at the function's `lexicalEnvironment = {"b":{y:2}}`
        b= { y:3};
       //  at this point `lexicalEnvironment = {"b":{y:3}}`
        return b;  //returned {y:3}.
    }

When the function is invoked with a as its parameter.

_change(a); // obtained {y:3} but not captured.

I would love to include the beautiful explanation for why the value of a does not change outside the scope of the function in this answer here, but, do not want to duplicate the original answer. Would like to share the relevant part though,

In practical terms, this means that if you change the parameter itself (as with a), that won't affect the item that was fed into the parameter. But if you change the INTERNALS of the parameter, such as b.y = 3, that will propagate back up.

Again, printing their values in the global lexical scope.

console.log(a.y); // still in the global lexical environment a.y = 2;
console.log(a.x); // `a.x` is undefined in the global Lexical Environment. 
Community
  • 1
  • 1
BatScream
  • 19,260
  • 4
  • 52
  • 68
  • What I dont understand is why is the reference of the 'a' not changed to {y:2} when i called the function. Please could you elaborate on this. Thanks – user2713706 Jan 09 '15 at 08:48
  • @user2713706 - Please see my edited answer. And read the informative answer i have linked to. – BatScream Jan 09 '15 at 08:59