Я использую for для присвоения значения массиву, но когда я печатаю массив, он просто подставляет последнее значение в полный массив - PullRequest
2 голосов
/ 07 августа 2020

Я создал массив, используя класс массива размером 8 * 8, и заполнил его фиктивным объектом с помощью fill. и после этого я создал for и присвоил значения. но когда я печатаю массив. то же значение существует для всего поля.

var gridSize = 8;
    const colorname = ["Red", "Orange", "Green", "Blue", "Purple", "Yellow"];

var gameGrid = new Array(gridSize * gridSize).fill({
        loc: null,
        color: null,
        index: null,
        value: null
    });
fillTheGrid();

function fillTheGrid() {
        for (var i = 0; i < gridSize * gridSize; i++) {
            addElement(i)
        }
}


// actual code Is big so im using I for index and value 
function addElement(i){
        gameGrid[i].loc = i;
        let randomColor = Math.floor(Math.random() * colorname.length);
        gameGrid[i].color = colorname[randomColor];
        gameGrid[i].index = i;
        gameGrid[i].value = i;
}

log(gameGrid);

ожидаемый результат

[{"loc":1,"color":"Green","index":1,"value":1},{"loc":2,"color":"Red","index":2,"value":2},......,{"loc":63,"color":"Green","index":63,"value":63}]

, но я получаю

[{"loc":63,"color":"Green","index":63,"value":63},...,{"loc":63,"color":"Green","index":63,"value":63}]

, то есть я получаю такое же значение для все

Ответы [ 2 ]

4 голосов
/ 07 августа 2020

В JS объекты передаются по ссылке, поэтому, когда вы делаете

var gameGrid = new Array(gridSize * gridSize).fill({
    loc: null,
    color: null,
    index: null,
    value: null
});

, один и тот же объект помещается в каждое место - если вы обновляете какой-либо из них, вы обновляете «все» из них. Что вам нужно сделать, так это поместить разные объекты в каждое место, выполнив:

var gameGrid = new Array(gridSize * gridSize).fill(null).map(i => ({
    loc: null,
    color: null,
    index: null,
    value: null
});

var gridSize = 8;
    const colorname = ["Red", "Orange", "Green", "Blue", "Purple", "Yellow"];

var gameGrid = new Array(gridSize * gridSize).fill(null).map(i => ({
        loc: null,
        color: null,
        index: null,
        value: null
    }));
fillTheGrid();

function fillTheGrid() {
        for (var i = 0; i < gridSize * gridSize; i++) {
            addElement(i)
        }
}


// actual code Is big so im using I for index and value 
function addElement(i){
        gameGrid[i].loc = i;
        let randomColor = Math.floor(Math.random() * colorname.length);
        gameGrid[i].color = colorname[randomColor];
        gameGrid[i].index = i;
        gameGrid[i].value = i;
}

console.log(gameGrid);
1 голос
/ 07 августа 2020

Если вы посмотрите описание метода Array.prototype.fill () в MDN, там написано:

Если первый параметр является объектом, каждый слот в массив будет ссылаться на этот объект.

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

Следующий фрагмент кода демонстрирует это поведение

let arr = Array(3).fill({});
arr[0].a = "hello";

arr.forEach(obj => console.log(obj));

Решение:

Нет необходимости изначально заполнять массив объектами, вы можете просто каждый раз создавать новый объект addElement() функция, добавьте пары ключ-значение во вновь созданный объект и добавьте этот объект в массив.

var gridSize = 8;
const colorname = ['Red', 'Orange', 'Green', 'Blue', 'Purple', 'Yellow'];

var gameGrid = new Array(gridSize * gridSize).fill(null);
fillTheGrid();

function fillTheGrid() {
  for (var i = 0; i < gridSize * gridSize; i++) {
    addElement(i);
  }
}

function addElement(i) {
  const obj = {};
  obj.loc = i;
  let randomColor = Math.floor(Math.random() * colorname.length);
  obj.color = colorname[randomColor];
  obj.index = i;
  obj.value = i;
  
  gameGrid[i] = obj;
}

console.log(gameGrid);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...