请尝试了解哪里出错。
我有一个数组table
和两个函数appendRow
和appendCol
。
如果我首先执行appendCol
它的工作正确,并且在表'y'中的每个数组中都附加了元素。
但是,如果我先执行'appendRow',然后appendCol
'y'将两次加到表中的第一个和最后一个数组。
我不明白为什么。
我的代码如下:
var table = [
['x', 'x', 'x', 'x'],
['x', 'x', 'x', 'x'],
['x', 'x', 'x', 'x'],
['x', 'x', 'x', 'x'],
['x', 'x', 'x', 'x']
]
var appendRow = () => {
var newTable = table;
newTable.push(newTable[0])
table = newTable
console.log(table)
}
var appendCol = () => {
var newTable = table;
newTable.forEach((element) => {
element.push("y")
})
table = newTable;
console.log(table);
}
appendRow();
appendCol();
链接到jsfiddle
执行后你可以看到控制台。
尝试评论第一个功能,第二个工作正确
答案 0 :(得分:3)
当您运行newTable.push(newTable[0])
时,您没有推送第一个子数组的副本,而是推送对该子数组的引用,所以现在newTable
包含对该子数组的两个单独引用子数组,意味着你将迭代两次,然后将"y"
推送到它两次。
为了解决此问题,您可以确保在appendRow()
中实际复制子数组,而不仅仅是引用它:
newTable.push(newTable[0].slice())
不带任何参数的slice()
方法将返回数组的副本。
另一方面,由于引用了数组(和其他对象类型),因此在newTable
和table
之间重新分配并没有真正完成任何事情。
答案 1 :(得分:3)
在appendRow函数中,您将引用推送到最后一行的第一行,而不是克隆/副本。因此,当你遍历appendCol函数中的行时,第一行会获得两次附加的值,因为它有两次 - 作为第一行,并且引用它作为最后一行。
您可以使用slice()
函数创建行的克隆。我还简化了所有table
/ newTable
内容,这些内容完全没有必要(同样是因为它创建引用而不是克隆),并将控制台日志字符串化以便于阅读:
var table = [
['x', 'x', 'x', 'x'],
['x', 'x', 'x', 'x'],
['x', 'x', 'x', 'x'],
['x', 'x', 'x', 'x'],
['x', 'x', 'x', 'x']
]
console.log(JSON.stringify(table));
var appendRow = () => {
table.push(table[0].slice());
console.log(JSON.stringify(table));
}
var appendCol = () => {
table.forEach((element, index, array) => {
element.push("y");
});
console.log(JSON.stringify(table));
}
appendRow();
appendCol();

此处它也在JSFiddle中更新:https://jsfiddle.net/gy97p92d/4/