Edit: Turns out I placed a var inside my array in a for loop, which creates references to that variable, not copies of it. When I then try to change the var inside the array, I change what it references to, so the change will happen for all other objects referencing to it as well
I have tried making a js animation, but I run into a problem when I want to change a array item inside a object, inside a array..
Here is a simplified demonstration of my problem:
function Rect(x, y, s, c) {
this.x = x,
this.y = y,
this.s = s
this.c = c;
}
function start() {
let rects = [];
let c = [0,0,0];
let x = 0;
for (i = 0; i < 10; i++) {
rects.push(new Rect(x, 50, 100, c));
x += 110;
}
document.getElementById("txt0").innerHTML = "Values before value change";
document.getElementById("txt1").innerHTML = rects[0].c;
document.getElementById("txt2").innerHTML = rects[1].c;
// I change value in one of the array-elements
rects[0].c[0] = 1;
document.getElementById("txt3").innerHTML = "Values after value change";
// Why is the value changed for all my array-elements?
document.getElementById("txt4").innerHTML = rects[0].c;
document.getElementById("txt5").innerHTML = rects[1].c;
}
window.onload = start;
I tried to rewrite a general simplified example to recreate the problem, but then I did not get the problem:
function My_constructor() {
this.my_array = [0, 0, 0];
}
let my_objects = [];
for (i = 0; i < 10; i++) { my_objects.push(new My_constructor()); }
// Print object 0 and 1 from array
document.getElementById("txt1").innerHTML = my_objects[0].my_array;
document.getElementById("txt2").innerHTML = my_objects[1].my_array;
// Change parameter in one of the objects from the array
my_objects[0].my_array[0] = 1;
document.getElementById("txt3").innerHTML = my_objects[0].my_array;
document.getElementById("txt4").innerHTML = my_objects[1].my_array;
Does anyone know why this may be?
simplified:
let a=[1,2,3]
let b = a
b[0] = 777
console.log(a) // outputs [ 777, 2, 3 ]
this is because in js:
arrays are reference values, so when you try to copy it using the = it will only copy the reference to the original array and not the value of the array. To create a real copy of an array, you need to copy over the value of the array under a new value variable. That way this new array does not reference to the old array address in memory.
the problematic operation is rects.push(new Rect(x, 50, 100, c));
,
the c
is the same across loop iterations.
so when changing it later on, you're affecting... all references to that memory space.
either move the let c = [0,0,0];
statement into the loop, or clone it using the spread operator[...c]
, i.e rects.push(new Rect(x, 50, 100, [...c]));