1

I'm new to javascript and I've been going through some exercises but I can't figure out why this code works like this,

    let newArray = [];
    let arr1 = [];
    for (let i = 0; i < 2; i++) {

      for (let j = 0; j < 2; j++) {

        arr1.push(0);
        //console.log('Arr1:',arr1); 
      }

      newArray.push(arr1);
      //console.log('New Array:', newArray)
      
    }
    console.log(newArray);
  

According to me, this block of code should output [[0,0][0,0,0,0]] but the real output is [[0,0,0,0][0,0,0,0]].

I tried console logging after every iteration(by removing the comments) and I can't seem to find where it goes wrong. It seems like it all goes well until the last log. I'd appreciate your help.

g97
  • 35
  • 5
  • 2
    `newArray` contains `arr1` twice. After the first `newArray.push(arr1)`, the value that was just added to `newArray` is a reference to `arr1` not the values of `arr1`. After that, when you modify `arr1`, the first value in `newArray` is also modified. – Titus Oct 13 '21 at 00:05
  • 1
    Oh, so even if I've already pushed `arr1` once, if I modify it after that, the pushed `arr1` is modified too? – g97 Oct 13 '21 at 00:08
  • Yes, that is correct, you can clone the array if you want to get the result that you've mentioned, something like `newArray.push([...arr1])`. `[...arr1]` will create a new array that contains all the value of `arr1` at that point. – Titus Oct 13 '21 at 00:11
  • Thanks but what about this code: (I dont know how to format multiple lines as code so I will post all code in next comment) – g97 Oct 13 '21 at 00:23
  • let newArray = []; let arr1 = [1,2,3,4,5,6]; newArray.push(arr1); console.log(newArray); arr1=[7,8,9,10]; newArray.push(arr1) console.log(newArray); – g97 Oct 13 '21 at 00:23
  • I push `arr1` and then modify it and push it again but `newArr` displays both arrays in the output, not the same one twice. – g97 Oct 13 '21 at 00:23
  • In that case, `arr1=[7,8,9,10]` redefines the variable `arr1` to a new array. So, the first statement `let arr1 = [1,2,3,4,5,6];` sets the `arr1` variable as a reference to `[1,2,3,4,5,6]` and then `arr1=[7,8,9,10];` sets `arr1` as a reference to `[7,8,9,10]`. In the code from your question, the `arr1` variable is always a reference to the same array. – Titus Oct 13 '21 at 00:26
  • I see now. So when I use push, it just modifies `arr1`, but when I use `arr1=[7,8,9,10]` it creates a new array with those values. Right? – g97 Oct 13 '21 at 00:33
  • Yes, something like that. Think of `arr1` as an address that points to same value, in the code from the question it always points to the same value, in the code from the comment it points to two different values. My explanation is probably not that good. You should look into what **values and references** are and how they work in **JavaScript** – Titus Oct 13 '21 at 00:37
  • It makes sense for now. I'll probably learn about values and references when I start learning OOP. Thanks a lot for helping me. – g97 Oct 13 '21 at 00:41

2 Answers2

1

One way to do it is to avoid using push() function and use concat() function instead. More about it on existing discussion.

You would have something like:

newArray = newArray.concat(arr)
ad007
  • 146
  • 4
  • 1
    Thanks but I was just curious about how that piece of code worked like that. Wasn't trying to copy arrays. – g97 Oct 13 '21 at 07:28
1

You should use Array#slice or spread syntax to copy the array instead of pushing the same reference multiple times, since subsequent changes will continue to be reflected.

let newArray = [];
let arr1 = [];
for (let i = 0; i < 2; i++) {
  for (let j = 0; j < 2; j++) {
    arr1.push(0);
  }
  newArray.push(arr1.slice());
}
console.log(JSON.stringify(newArray));
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • Thanks but I was just curious about how that piece of code worked like that. Wasn't trying to copy arrays. – g97 Oct 13 '21 at 07:28
  • It works like that because you pushed the same array twice, then added more elements to that array. Changes to that array are reflected in both references to that array, so it displays two arrays with 4 elements (actually the same array with 4 elements twice). – Unmitigated Oct 13 '21 at 12:14
  • I still haven't learned about oop or the differences of references and values. I was getting ahead of myself. Just couldn't get my head around it. Thanks though. – g97 Oct 13 '21 at 16:44