Debugging - Use Caution When Reinitializing Variables Inside a Loop

Tell us what’s happening:
Hello, I want understand. If row is a global variable, why the result is not like this?:
[ [ 0, 0 ],
[ 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ] ]

Your code so far
I solved the problem itself, but my question is about the first output:
[ [ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ] ]
I want to understand the behaviour of this compiler an Why this is the result and no the first.

function zeroArray(m, n) {
  // Creates a 2-D array with m rows and n columns of zeroes
  let newArray = [];
  let row = [];
  for (let i = 0; i < m; i++) {
    // Adds the m-th row into newArray

    for (let j = 0; j < n; j++) {
      // Pushes n zeroes into the current row to create the columns
      row.push(0);
    }
    // Pushes the current row, which now has n zeroes in it, to the array
    newArray.push(row);
    console.log(newArray);
    console.log(" ");
  }
  return newArray;
}

let matrix = zeroArray(3, 2);
console.log(matrix);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.67

Challenge: Debugging - Use Caution When Reinitializing Variables Inside a Loop

Link to the challenge:

Let’s break down what’s going wrong:

  1. Setup
    m = 3
    n = 2
    newArray = []
    row = []

  2. First iteration of outer for loop
    The outer for loop is going to iterate m (3) times.

  3. Inner for loop
    This one is going to go n (2) times.

  4. row is empty. After row.push(0):
    row = [0]

  5. And again:
    row = [0, 0]

  6. After newArray.push(row):
    newArray = [0, 0]

    row and newArray are now both appear to be [0, 0].

  7. Second iteration of outer loop
    Two more zeroes get pushed into row.
    row = [0, 0, 0, 0]
    If we check newArray right now, we expect it to be [0, 0] because we haven’t pushed to it yet. But it’s not.
    newArray = [0, 0, 0, 0]

When we pushed row into newArray, we actually passed it a reference to row instead of the destructured contents of row. (Like you could get by changing newArray.push(row) to newArray.push([...row]), in which case the final result would look like the first example you gave.)

newArray thus actually looks like [row]. When you push row into it again, it looks like [row, row]. Every time you update row, you end up updating newArray because row can be globally accessed.

If you were to add row.splice(0) at the end right before returning newArray, row would be equal to [] and newArray would be equal to [ [], [], [] ].

I hope this makes some sense. Happy coding!

1 Like

Interesting! I undesrtand, that means… if I modify the row variable after the loop…
For example row=[ 1, 5, 6, 3 ];
Will the newArray be …
[ [ 1, 5, 6, 3 ]
[ 1, 5, 6, 3 ]
[ 1, 5, 6, 3 ]]
?

Thanks for your time!

That is a very good question. Funny enough, that wouldn’t happen. That’s because when you type row = [1, 5, 6, 3], you aren’t modifying row but rather creating a new array [1, 5, 6, 3] and telling the compiler that the variable row now references that one.

newArray would still have the same values as it did before, but you will now only be able to change it by directly accessing newArray.

On the other hand, if you were to directly mutate row by using array methods like pop(), push(), or splice(), you would be modifying newArray too, as long as row is still referencing the original array that was created when you initialized it with let row = [].

If you want to do some more reading, you can find a good stackoverflow thread here. Good luck!

Hi arct, sanOmar
I still don’t understand the explanation
" When we pushed row into newArray , we actually passed it a reference to row instead of the destructured contents of row . (Like you could get by changing newArray.push(row) to newArray.push([...row]) , in which case the final result would look like the first example you gave.)"

Can you explain it more details or maybe you have an article I can read to understand your explanation?

thank you