Prachi g
Prachi g

Reputation: 839

How do object references work internally in javascript

I am very new to javascript. I have written the simple code:

var temp = {}
var arr = []

temp['a'] = ['a']
arr.push(temp)
console.log(arr);

As expected, it prints:

[ { a: [ 'a' ] } ]

But then, when I append the following line to the previous code:

temp['b'] = ['b']
arr.push(temp);
console.log(arr);

I would have expected it to print:

[ { a: [ 'a' ] }, { a: [ 'a' ], b: [ 'b' ] } ]

But it prints:

[ { a: [ 'a' ], b: [ 'b' ] }, { a: [ 'a' ], b: [ 'b' ] } ]

Entire code for unexpected result: var temp = {} var arr = []

temp['a'] = ['a']
arr.push(temp)
console.log(arr);

temp['b'] = ['b']
arr.push(temp);
console.log(arr);

Why did the first element of array got updated?

The following code gave me expected result:

var temp = {}
var arr = []

temp['a'] = ['a']
arr.push(temp)
console.log(arr);

temp = {};
temp['a'] = ['a']
temp['b'] = ['b']
arr.push(temp);
console.log(arr);

How does adding temp = {} helped here?

Upvotes: 2

Views: 225

Answers (4)

Ben Aston
Ben Aston

Reputation: 55729

There are two data types in JavaScript - value types and reference types.

Value types are actually copied as they are sent between objects. This is because this is what you would expect for certain things like numbers and booleans.

Say I pass the number 1 to a function that stores it in an object A.

It would be surprising if I could then subsequently modify the value contained in A simply by modifying the value of the original number. Hence, pass by value. There are also optimizations that can be performed for value types.

Objects (i.e. everything other than number literals, boolean literals, null, undefined, and string literals*) are reference types in JavaScript and only their reference is passed around. This is largely for efficiency reasons. In your example, temp is an object. It is therefore passed by reference.

And so

temp['b'] = ['b']

Modifies the single existing instance of temp, thereby modifying the contents of arr, before you then also push temp into arr for a second time.

So you end up with an array containing two references to a single object temp, giving you the observed result.

* There is some complexity surrounding the string implementation that I am purposefully ignoring here.

Upvotes: 0

Amit Joki
Amit Joki

Reputation: 59232

In first case, arr[0] has temp's reference, arr[1] also has temp's reference. So, arr[0] and arr[1] have the same reference.

Hence updating the reference will update it everywhere where the reference is being referred.

In second case however, when you do temp = {} you're just reassigning temp to a new reference, before pushing it. So, there's no relationship between the arr[0]'s reference, and hence updating temp now, only affects it.

Upvotes: 1

Eudis Duran
Eudis Duran

Reputation: 782

Objects in Javascript are passed by reference. That is, only one object is created and the symbol that represents that object can be used but it will refer to the same object always.

Lets take a deeper look:

If I'm understanding your example correct, this part

var temp = {}
var arr = []

temp['a'] = ['a']
arr.push(temp)
console.log(arr);

Creates a local variable temp to which you add ['a'] to. You then push that into arr.

So at this point, arr references the object temp and looks like this:

[ { a: [ 'a' ] } ]

When you do this:

temp['b'] = ['b']
arr.push(temp);
console.log(arr);

The temp symbol which points to the original object containing ['a'] is updated, and so the arr will also get updated, so arr contains this at that point:

[ { a: [ 'a' ], b: [ 'b' ] }, { a: [ 'a' ], b: [ 'b' ] } ]

Finally,

You then do this instead:

temp = {};
temp['a'] = ['a']
temp['b'] = ['b']
arr.push(temp);
console.log(arr);

This creates a separate global variable temp, onto which you add both ['a'] and ['b']. This is global because it does not have the var keyword in the declaration/initialization. This then gets pushed into the arr. However, since it's a global variable and not the original local variable, you see this instead:

 [ { a: [ 'a' ] }, { a: [ 'a' ], b: [ 'b' ] } ]

Upvotes: 3

bitoiu
bitoiu

Reputation: 7484

The examples are not the same, it doesn't have to do with temp = {}.

In the first example you push temp twice, meaning arr has to references 2 temp.

After the first push you add another item to temp so within arr, if you had print it, you would have seen:

[ { a: [ 'a' ], b: [ 'b' ] } ]

So try this out on the console:

var temp = {}
var arr = []

temp['a'] = ['a']
arr.push(temp)
temp['b'] = ['b']
console.log(arr);

You'll see the result:

[ { a: [ 'a' ], b: [ 'b' ] } ]

Pushing another temp into arr is just going to result into two references into temp.

Upvotes: 0

Related Questions