0

I often give array elements properties so that I don't need to use nested arrays. However, when I copy an array element with array.push(array[0]) or even array[array.length] = array[0], they new element and the copied element are becoming linked- when I change a property of one, it changes that property of the other.

Here is the code:

var array = [{num: 0}, {num: 1}, {num: 2}, {num: 3}];
var i;
var nums = "";
array.push(array[0]);

//What the array looks like before anything is changed
for (i = 0; i < array.length; i += 1) {
    nums += array[i].num + " ";
}
console.log(nums);

array[0].num = 1;

//What the array looks like after changing only one element
nums = "";
for (i = 0; i < array.length; i += 1) {
    nums += array[i].num + " ";
}
console.log(nums);

When this is run, both the first and last elements of array are changed, despite only running array[0].num = 1. Does anyone know what's happening and how I can fix it?

  • 4
    Object values are *references*. Assigning an object reference from one place to another does not make a copy. – Pointy Aug 01 '18 at 18:03
  • @JamesFaix When you declined [this edit](https://stackoverflow.com/review/suggested-edits/20470584), did you even take a look at the jsfiddle link? The code was exactly the same, and the edit inlined the code directly in the post with a way to run/execute the snippet directly from SO. There was no reason why you should have rejected that edit there. – Blue Aug 01 '18 at 19:22
  • "*properties so that I don't need to use nested arrays*" - sorry, what? Can you expand on why you think you need an array of objects (or an array of arrays) instead of simply using an array of numbers? – Bergi Aug 01 '18 at 20:13

2 Answers2

0

This is happening because the elements of the array are objects. You are just assigning the reference to one object into multiple arrays. If you want to copy the data from the objects into totally new objects, you'll have to clone them. Something like this should do what you want for simple objects.

function clone(obj){
    return JSON.parse(JSON.stringify(obj));
}
var array = [{num: 0}, {num: 1}, {num: 2}, {num: 3}];
array.push(clone(array[0]));
sbrass
  • 905
  • 7
  • 12
0

array[0] is just a reference to the object {num: 0} at index 0 of your array. array.push(array[0]) pushes this reference to the back of the array. Anything you do to one of the references will effect the other, since they're pointing to the same thing.

This makes a deep copy of the object by accessing the underlying primitive:

var array = [{num: 0}, {num: 1}, {num: 2}, {num: 3}];

array.push({num: array[0].num});

console.log(array);
array[0].num = 1;
console.log(array);
ggorlen
  • 44,755
  • 7
  • 76
  • 106