Следующий код должен создать пустой массив, который содержит 7 пустых массивов, фактически сетку 7x7.

Доступ к элементам во вложенных массивах работает нормально, но попытка изменить их значения приводит к изменению значения всех элементов в одном столбце (поэтому изменение [1] [1] также приводит к изменению [0] [1], [2] [1] и т. Д.). ) . Я не могу понять почему.

var usage = new Array(7).fill(new Array(7).fill(0));

usage[1][1] += 1;

https://jsfiddle.net/v3o4rwsz/

0
user3356802 13 Янв 2017 в 03:16

3 ответа

Лучший ответ

Это простая ловушка, в которую можно попасть. Ваш код эквивалентен:

var innerArray = [0,0,0,0,0,0,0]; // .fill(0)
var usage = [innerArray, innerArray, innerArray, innerArray,
             innerArray, innerArray, innerArray]; // .fill(innerArray)

console.log(usage[0]==innerArray); // true
console.log(usage[1]==innerArray); // true

Чтобы получить желаемый результат, вам нужно создать новый массив для каждого используемого элемента, например:

var usage = [];
for (var i=0; i<7; i++) {
    usage.push(new Array(7).fill(0));
}
0
Chas Brown 13 Янв 2017 в 01:04

Содержимое первого fill оценивается только один раз - создается второй массив, а затем он дублирует этот массив 7 раз, поэтому все они связаны.

Это эквивалентно:

var t1 = new Array(7).fill(0);

var t2 = t1;
var t3 = t1;
var t4 = t1;
var t5 = t1;
var t6 = t1;
var t7 = t1;

t2[3] = "duplicate"

console.log(t1);
console.log(t2);
console.log(t3);

Который покажет то же значение в t1 для t7.

0
K Scandrett 13 Янв 2017 в 01:04

Я считаю, что такое поведение вызвано тем, что вы используете .fill(). Если вы посмотрите на определение этой функции здесь вы увидите, что он заполняет массив статическим значением

Это означает, что когда вы ссылаетесь на usage[1][1], вы ссылаетесь на тот же массив, который существует в usage[0][1], usage[2][1] и так далее.

Вы можете заполнить массив циклом for, как показано ниже.

var usage2 = new Array();

for(var i=0;i<7;i++) { 
    usage2.push(new Array(7).fill(0));
}

Теперь, когда вы проверите свои значения, вы увидите ожидаемый результат, когда изменяется только один массив, как на скриншоте ниже с моей консоли Chrome.

JS Console Screenshot

0
James 13 Янв 2017 в 01:07