注意:我只是一个编码新手,所以这个问题的核心可能存在明显的错误或误解。
本质上,我需要在 JavaScript 中“按值”深度复制多维数组到未知深度。我原以为这需要一些复杂的递归,但似乎在 JavaScript 中您只需要深复制一个级别就可以按值复制整个数组。
举个例子,这是我的测试代码,使用了一个故意复杂的数组。
function test() {
var arr = [ ['ok1'],[],[ [],[],[ [], [ [ ['ok2'], [] ] ] ] ] ];
var cloned = cloneArray(arr);
arr = ''; // Delete the original
alert ( cloned );
}
function cloneArray(arr) {
// Deep copy arrays. Going one level deep seems to be enough.
var clone = [];
for (i=0; i<arr.length; i++) {
clone.push( arr[i].slice(0) )
}
return clone;
}
在我运行这个测试(Ubuntu 上最新的稳定版 Chrome 和 Firefox)时,即使是数组的最深部分似乎也被克隆中的值成功复制了,即使在原始文件被删除之后,尽管切片() “复制”只深入了一层。这是 JavaScript 中的标准行为吗?我可以依靠它来为旧版浏览器工作吗?
最佳答案
您的测试在是否制作真实副本方面存在缺陷,这使得您得出的结论是错误的,即您正在获取嵌套数组中所有数据的完整副本。您只是在进行两级复制,而不是 N 级复制。
Javascript 是一种垃圾回收语言,因此您实际上并没有删除变量或对象,即使您尝试这样做也不会影响在代码中其他地方引用的同一个变量。要查看您是否真的拥有一个完全独立的副本,请尝试将一个对象嵌套两层深,然后更改原始数组中该对象的属性。你会发现同一个对象在克隆的数组中发生了变化,因为你没有进行深度克隆。两个数组都引用了完全相同的对象。
这是 an example .
function cloneArray(arr) {
// Deep copy arrays. Going one level deep seems to be enough.
var clone = [];
for (i=0; i<arr.length; i++) {
clone.push( arr[i].slice(0) )
}
return clone;
}
var x = [[{foo: 1}]];
var y = cloneArray(x);
x[0][0].foo = 2;
// now see what the value is in `y`
// if it's 2, then it's been changed and is not a true copy
// both arrays have a reference to the same object
console.log(y[0][0].foo); // logs 2
如果第三层也是另一个数组,也会出现同样的结果。 您将必须递归遍历每个对象类型的元素,然后克隆该对象本身以获得嵌套数组中所有内容的完整克隆。
如果您想要执行深度复制(到任意级别)并适用于所有数据类型的代码,请参阅 here .
仅供引用,您的 cloneArray()
函数假定数组的所有第一级成员本身都是数组,因此如果它包含任何其他类型的值则不起作用。
关于javascript - 对于 JavaScript 多维数组的深拷贝,深入一层似乎就足够了。这是真的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25100714/