Unexpected behavior using Array Map on an Array In

2020-01-29 02:52发布

问题:

I've ran into an issue with the new Array.prototype.fill method due to unexpected output when using it with Array.prototype.map. For example:

// Initialize our n x n matrix and fill with 0's
let M = Array(3).fill(Array(3).fill(0));

M.map(function (row, i) {
    row[i] = i;
    return row;
}); //=> [[0, 1, 2], [0, 1, 2], [0, 1, 2]]

In the above example, I expect the output to be the same as the below example:

let  M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];

M.map(function (row, i) {
    row[i] = i;
    return row;
}); //=> [[0, 0, 0], [0, 1, 0], [0, 0, 2]]

However it isn't. For some reason the result being returned in the first example is being used as the row value in the next iteration. Any ideas why this might be occuring? I'm using the 6to5ify transform for browserify to transform the ES6 code to ES5.

回答1:

Your code is equivalent to:

let inner = Array(3).fill(0);
let M = Array(3).fill(inner);

When you pass inner to .fill(), it doesn't make copies of it, the M array contains 3 references to the same array. So anything you do to one element of M happens to them all.

You need to make new arrays for each element of M:

let M = [];
for (var i = 0; i < 3; i++) {
    M.push(Array(3).fill(0));
}