【问题标题】:Keep original array intact, change local copy in function保持原始数组不变,在函数中更改本地副本
【发布时间】:2013-07-29 10:46:46
【问题描述】:

即使我在函数内部处理克隆,嵌套数组也会更改。保留a 数组的最有效方法是什么? JSBin here.

var a = [[2,3],[1,5,2],[3,7,2]];
function c(a) {
  var l = a.slice(0);
  console.log('in func, before change',l);
  l[1].splice(1,1);
  console.log('in func, after change',l);
}
console.log('before call', a);
c(a);
console.log('after call',a);

【问题讨论】:

标签: javascript pass-by-value


【解决方案1】:

您的代码在一维数组上运行良好:

function c(a) {
  var l = a.slice(0);
  console.log('in func, before change',l);
  l[1] = 17;
  console.log('in func, after change',l);
}

var a = [2,3,1,5,2,3,7,2];
console.log('before call', a);
c(a);
console.log('after call',a);

输出:

“通话前” [2、3、1、5、2、3、7、2] “在 func 中,在更改之前” [2、3、1、5、2、3、7、2] “在 func 中,更改后” [2, 17, 1, 5, 2, 3, 7, 2] “通话后” [2, 3, 1, 5, 2, 3, 7, 2]

事实上,它是一个 2D 阵列正在吸引您。查看克隆 2D javascript 数组的堆栈溢出响应:

Multidimensional Array cloning using javascript

现在使用这个代码:

Array.prototype.clone = function() {
    var arr = this.slice(0);
   for( var i = 0; i < this.length; i++ ) {
        if( this[i].clone ) {
            //recursion
            arr[i] = this[i].clone();
        }
    }
    return arr;
}

function c(a) {
  var l = a.clone();
  console.log('in func, before change',l);
  l[1].splice(1,1);
  console.log('in func, after change',l);
}

var a = [[2,3],[1,5,2],[3,7,2]];
console.log('before call', a);
c(a);
console.log('after call',a);

输出:

“通话前” [[2, 3], [1, 5, 2], [3, 7, 2]] “在 func 中,在更改之前” [[2, 3], [1, 5, 2], [3, 7, 2]] “在 func 中,更改后” [[2, 3], [1, 2], [3, 7, 2]] “通话后” [[2, 3], [1, 5, 2], [3, 7, 2]]

【讨论】:

    【解决方案2】:

    .slice 不进行“深度”复制。由于 'a' 的每个元素都是一个数组,iteslf,'a' 的元素是对那些内部元素的引用,否则就是匿名元素。

    数组“l”保存引用的副本,复制的引用仍然指向它们所引用的相同“对象”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-18
      • 2020-10-04
      • 2022-11-12
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多