对于每个工作不正确,帮助理解原因



请尝试了解错误所在。

我有一个数组table和两个函数appendRowappendCol

如果我先执行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

执行后可以看到控制台。

尝试评论第一个功能和第二个工作正确

当你运行newTable.push(newTable[0])时,你不是在推送第一个子数组的副本,而是在推送对该子数组的引用,所以现在newTable包含对该子数组的两个单独引用,这意味着你将迭代它两次,随后"y"推送到它两次。

为了解决这个问题,你可以确保你实际上复制了appendRow()中的子数组,而不仅仅是引用它:

newTable.push(newTable[0].slice())

不带任何参数的slice()方法将返回数组的副本。

另一方面,由于引用了数组(和其他对象类型(,因此在newTabletable之间重新分配并不能真正完成任何事情。

在 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/

最新更新