Reputation: 839
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
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
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
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
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