-1

Here's some code:

var a = [1,2,3];
var b = [5,4];
var c = 6;
a.push(b);
console.log(a);
b[0] = 1;
console.log(a);
console.log(b);
a.push(c);
console.log(a);
c = 7;
console.log(a);

Here's the result in console:

[ 1, 2, 3, [ 5, 4 ] ]
[ 1, 2, 3, [ 1, 4 ] ]
[ 1, 4 ]
[ 1, 2, 3, [ 1, 4 ], 6 ]
[ 1, 2, 3, [ 1, 4 ], 6 ]

Can someone tell me why changing the first item of b array after pushing it to the a array also affects the a array here? For example when I change the value of c variable pushed to a array it doesn't affect the a array and that's what I want to happen with b as well.

JZ555
  • 617
  • 2
  • 7
  • 16
  • 1
    To gauge your current understanding, how would you expect `b = [5,4]; c = b; c[0] = 1; console.log(b);` to behave? – apsillers Oct 01 '14 at 16:06
  • console.log(b) should be [5,4] but I'm guessing it's gonna be [1,4]. But that's what I'm asking, why this happens? – JZ555 Oct 01 '14 at 16:13
  • Sure; I just wanted to make sure that your confusion wasn't related to `push` specifically, but applies more broadly to array references. – apsillers Oct 01 '14 at 16:14

1 Answers1

4

Objects in javascript (like arrays) are passed around as references. So, when you do:

a.push(b)

You are pushing a reference to b into the array a. If you later change b, there is only one b so it will change in all places that refer to it, including in the array.

Another way to say this is that a.push(b) does not make a copy of b. What was pushed into the array just points to the same b you've always had so if you change b, the reference in the array just points to the one b there is so looking at the value through the array will see the change too.


If you truly want a copy (that won't be affected by changes to the original) pushed into the array, you can make an explicit copy using .slice().

var a = [1,2,3];
var b = [5,4];
var c = 6;
a.push(b.slice());   // push a shallow copy of b

This is a fairly fundamental thing to grasp when learning javascript. When you pass or assign objects in javascript (and an array is one type of object), a copy is not made. Instead, you end up with more than one part of your code all pointing to the exact same object. This is obviously a feature that can be taken advantage of, but it means that when you want an independent copy that has no connection to the original, you have to explicitly make a copy.

To contrast with this, primitives such as Boolean or Number are assigned or passed as a copy.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • +1; fot additional guidance on `.slice()`, see [Copying array by value in javascript](http://stackoverflow.com/questions/7486085/copying-array-by-value-in-javascript) – apsillers Oct 01 '14 at 16:15