Why is it that the output so weird! What is the fill method actually doing?
Expected output: [[0, 0, 0], [0, 5, 0], [0, 0, 0]]
Actual output: [[0, 5, 0], [0, 5, 0], [0, 5, 0]]
let matrix = new Array(3).fill(new Array(3).fill(0)); // creates a 2d Array and fills them with 0
matrix[1][1] = 5; // say
console.log(matrix);
4
The behavior you’re seeing is due to how Array.fill()
works with objects, particularly arrays in JavaScript. Let’s break down what’s happening:
let matrix = new Array(3).fill(new Array(3).fill(0));
In this line, new Array(3)
creates an array with three empty slots, which are then filled using fill(new Array(3).fill(0))
.
However, the issue arises because new Array(3).fill(0)
creates a single instance of an array [0, 0, 0]
, and this single instance is used to fill all three slots of the outer array. So, effectively, your matrix
array ends up looking like this:
matrix = [
[0, 0, 0], // All three inner arrays point to the same array object in memory
[0, 0, 0],
[0, 0, 0]
];
When you modify matrix[1][1] = 5;
, you’re modifying the same inner array that is referenced by all three slots of the outer array. Therefore, all rows reflect this change, resulting in the output:
[[0, 5, 0], [0, 5, 0], [0, 5, 0]]
To fix this and create a proper 2D array where each row is independent, you should initialize each row separately, like this:
let matrix = new Array(3);
for (let i = 0; i < matrix.length; i++) {
matrix[i] = new Array(3).fill(0);
}
This way, each row (matrix[i]
) gets its own array instance, and modifying one row won’t affect the others. So, modifying matrix[1][1] = 5;
would correctly give you:
[[0, 0, 0], [0, 5, 0], [0, 0, 0]]
This behavior of Array.fill()
where it fills with references to the same object (in this case, the inner array) is a common source of confusion when working with nested arrays and objects in JavaScript.
Daksh is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2