0

whenever i try to change the first object in the array's y, all the other objects y properties in my array also change, is there any way to prevent this, or a way to add multiple objects to an array that share the same properties ? i have been trying everything to fix this(i was creating a game that uses a similar array for bullets firing and whenever i changed the y property of the first item in my array all the other y properties in the array changed with it) and i thought that this might be the problem ?

var obj = {x:30,y:20};
var arr = [];
for(var i = 0;i<3;i++) {
arr.push(obj);
}
arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);
doubleOrt
  • 2,407
  • 1
  • 14
  • 34
  • 4
    Each index in the array contains a *reference* to the same object - so changing the value in one index will take effect for all. – tymeJV Dec 30 '15 at 21:19

4 Answers4

2

You can fix this by defining an object inside of .push().

This creates a new object for each element of the array, instead of the array containing multiple references to the same object.

var arr = [];
for(var i = 0;i<3;i++) {
arr.push({x:30, y:20});
}
arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);
IrkenInvader
  • 4,030
  • 1
  • 12
  • 23
1

In JavaScript, objects are stored in memory as pointers to the values inside the object. This is different to how primitive data types (int, char, etc.)

A good way to show this is to try printing out the object, vs printing out an int:

HTML:

<div id="anelementhere"></div>
<div id="anotherelementhere"></div>

JS:

var x = 5;
var obj = {x:30,y:20};
document.getElementById("anelementhere").innerHTML = x;
document.getElementById("anotherelementhere").innerHTML = obj;

JSFiddle: https://jsfiddle.net/d3ohpqqp/

You should be able to see something akin to:

5
[object Object]

Now, knowing this, what's stored in the array is NOT {{x:30, y:20}, {x:30, y:20}, {x:30, y:20}}, but {[object Object], [object Object], [object Object]}, which all point to ONE {x:30, y:20}

This is what makes all the y properties change after changing one. Now a simple solution, as @IrkenVader has shown is where you initialize the object when you put it into the array.

However, if for some reason you still want the original object outside of the array, this is another solution:

var obj = {x:30,y:20};
var arr = [];
for(var i = 0;i<3;i++) {
    arr.push({x:obj.x, y:obj.y});
}
arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);

JSFiddle: https://jsfiddle.net/9gzyr38x/

michal
  • 226
  • 2
  • 11
0

you are making a single obj and passing a reference to the same object, 4 times in your array

instead you could try creating new objects in each iteration:

var arr = [];
for(var i = 0;i<3;i++) {
  arr.push({x:30,y:20});
}
arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);

You could also look up the various ways to "clone" an object. angular, jquery and underscore all provide methods to do so, or you can check out How to clone js object?

Plato
  • 10,812
  • 2
  • 41
  • 61
0

As well as the answer @IrkenInvader gave, you can also use jQuery to very easily perform a deep-copy of an object:

var obj = {x: 30, y: 20};
var arr = [];
for(var i  = 0; i < 3; i++) {
  arr.push(jQuery.extend(true, {}, obj));
}

arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);
Community
  • 1
  • 1
Matthew Herbst
  • 29,477
  • 23
  • 85
  • 128