我使用Array()构造函数创建大小为3的空数组,然后使用forEach()或Array.fill()填充数组,但是当我试图更改/变异数组中的任何元素时,其他数组中任何类似成员的值都被设置为分配给任何其他成员的最后一个值。Creationn方法:
const createBoard = () => {
let row = Array(3);
const cellDS = {
isClcicked: false,
toPlayer: null,
cellID: null,
};
row.fill(cellDS);
let gameBoard = Array(3);
gameBoard.fill(row);
console.log("board created");
return gameBoard;
};当我更改第一行第一个元素的单元格ID时,会得到以下结果:
[[
{ isClicked: false, toPlayer: null, cellID: 1 },
{ isClicked: false, toPlayer: null, cellID: 1 },
{ isClicked: false, toPlayer: null, cellID: 1 },
],
[
{ isClicked: false, toPlayer: null, cellID: 1 },
{ isClicked: false, toPlayer: null, cellID: 1 },
{ isClicked: false, toPlayer: null, cellID: 1 },
],
[
{ isClicked: false, toPlayer: null, cellID: 1 },
{ isClicked: false, toPlayer: null, cellID: 1 },
{ isClicked: false, toPlayer: null, cellID: 1 },
]]isClicked和toPlayer也是如此。
Vuex代码:
const state = { gameBoard: [] };
const getters = {
getGameBoard: (state) => state.gameBoard,
};
const actions = {
createBoard: ({ commit }) => {
commit("setBoard");
},
editBoard: ({ commit }) => {
commit("changeBoard");
},
};
const mutations = {
setBoard: (state) => {
state.gameBoard = createBoard();
},
changeBoard: (state) => {
console.log("Before: " + state.gameBoard[0][0]["cellID"]);
state.gameBoard[0][0]["cellID"] = 1;
console.log("After: " + state.gameBoard[0][0]["cellID"]);
console.log("After: " + state.gameBoard[0][1]["cellID"]);
},
}解决方案: fill()在整个应用程序中创建元素的精确静态副本,不能简单地在数组(3)将返回的空数组上使用forEach,这本身是没有意义的(Undifiend)。因此,您可以用空填充它,然后在其上使用forEach()。
发布于 2020-11-22 15:34:31
您需要了解JS中的对象以及值类型和对象类型之间的区别。在您的示例中,fill方法只使用相同的对象填充数组,如果您更改该对象的某个字段,它将在数组的所有条目中更改,因为这是完全相同的对象。该数组只存储对此对象的引用,但不存储该对象的副本。
如果希望创建该对象的独立副本,则应在for循环中创建它们,以便通过数组自身的对象副本填充数组的每个元素。
for (let ind=0; ind< row.length; ind++) {
row[ind] = Object.assign({}, cellDS);
}请记住,使用Object.assign,您不会复制所有内部对象道具,而只是值类型道具。对象类型道具将指向与原始对象相同的对象。要对对象进行深度复制,您应该使用类似于cloneDeep包的lodash函数。
https://stackoverflow.com/questions/64955548
复制相似问题