对于JavaScript多维数组的深层副本,深入一层似乎就足够了。这是真的吗?

use*_*911 5 javascript arrays multidimensional-array

注意:我只是一个新手程序员,所以这个问题的核心可能是明显的错误或误解。

本质上,我需要将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;
}
Run Code Online (Sandbox Code Playgroud)

在我运行此测试(Ubuntu上最新稳定的Chrome和Firefox)的过程中,即使删除了原始数组,即使数组最深的部分也似乎已成功通过克隆中的值成功复制,即使slice_()复制”仅深入了一层。这是JavaScript中的标准行为吗?我可以依靠它来运行较旧的浏览器吗?

jfr*_*d00 2

您的测试对于是否正在制作真实副本存在缺陷,这使得您的结论不正确,即您获得了嵌套数组中所有数据的完整副本。你只是进行了两级副本,而不是N级副本。

Javascript 是一种垃圾收集语言,因此您实际上不会删除变量或对象,即使您尝试过,如果在代码中的其他地方引用了同一变量,也不会影响该变量。要查看是否确实拥有完全独立的副本,请尝试将对象嵌套两层,然后更改原始数组中对象的属性。您会发现克隆数组中的同一对象发生了变化,因为您没有进行深度克隆。两个数组都引用完全相同的对象。

这是一个例子

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
Run Code Online (Sandbox Code Playgroud)

如果第三层也是另一个数组,也会发生相同的结果。 您必须递归遍历对象类型的每个元素,然后克隆该对象本身以获得嵌套数组中所有内容的完整克隆。

如果您想要执行深度复制(任意级别)并适用于所有数据类型的代码,请参阅此处

仅供参考,您的cloneArray()函数假设数组的所有第一级成员本身都是数组,因此如果它包含任何其他类型的值,则该函数不起作用。