【问题标题】:Clone Multidimensional Array in javascript在javascript中克隆多维数组
【发布时间】:2026-02-24 14:05:02
【问题描述】:

我想制作一个多维数组的克隆,这样我就可以在不影响主数组的情况下与克隆数组一起玩。

我正在使用以下函数:

Array.prototype.clone = function () { 
   var newArray = new Array(this.length);
     for(var i=0; i < this.length; i++ ){
        newArray[i] = this[i];
   }
   return newArray;
};

但问题是因为它使用数组原型,所以它会克隆我的所有数组。所以任何人都可以告诉我这样做的最佳方法是什么。

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    我发现这种方法比meouw的更好:

    var source = [
      [1, 2, {c:1}],
      [3, 4, [5, 'a']]
    ];
    
    // Create a new method ontop of the "Array" primitive prototype:
    Array.prototype.clone = function() {
      function isArr(elm) {
        return String(elm.constructor).match(/array/i) ? true : false;
      }
    
      function cloner(arr) {
        var arr2 = arr.slice(0),
            len = arr2.length;
    
        for (var i = 0; i < len; i++)
          if (isArr(arr2[i]))
            arr2[i] = cloner(arr2[i]);
    
        return arr2;
      }
      return cloner(this);
    }
    
    // Clone
    var copy = source.clone();
    
    // modify copy
    copy[0][0] = 999;
    
    console.dir(source);
    console.dir('**************');
    console.dir(copy);

    另一种方法,它只能处理以原语
    为值的数据集(StringNumbersObjects):

    var source = [
      [1,2, {a:1}],
      ["a", "b", ["c", 1]]
    ];
    
    // clone "srouce" Array
    var copy = JSON.parse(JSON.stringify(source));
    
    // modyfy clone
    copy[0][0] = 999;
    
    // print both arrays
    console.dir(copy)
    console.log('***********')
    console.dir(source)

    【讨论】:

    • 我已经发布了一个改进的答案:)
    【解决方案2】:

    vsync 是正确的,我的第一个答案无法处理 var a = [[1,2],[3,4]];
    所以这里有一个改进的版本

    var a = [[1,2],[3,4]];
    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;
    }
    
    var b = a.clone()
    
    console.log(a);
    console.log(b);
    
    b[1][0] = 'a';
    
    console.log(a);
    console.log(b);
    
    //[[1, 2], [3, 4]]
    //[[1, 2], [3, 4]]
    //[[1, 2], [3, 4]]
    //[[1, 2], ["a", 4]]
    

    【讨论】:

    • 第一个答案对我来说不能正常工作,但这个答案很完美。谢谢!
    • 非常感谢您在这里发布此方法。我对它进行了另一项改进:if( this[i] &amp;&amp; this[i].clone ) { 支持 sparse 数组(或者当某些值为 null 时您调用的任何数组)
    【解决方案3】:

    你需要使用递归

    var a = [1,2,[3,4,[5,6]]];
    
    Array.prototype.clone = function() {
        var arr = [];
        for( var i = 0; i < this.length; i++ ) {
    //      if( this[i].constructor == this.constructor ) {
            if( this[i].clone ) {
                //recursion
                arr[i] = this[i].clone();
                break;
            }
            arr[i] = this[i];
        }
        return arr;
    }
    
    var b = a.clone()
    
    console.log(a);
    console.log(b);
    
    b[2][0] = 'a';
    
    console.log(a);
    console.log(b);
    
    /*
    [1, 2, [3, 4, [5, 6]]]
    [1, 2, [3, 4, [5, 6]]]
    [1, 2, [3, 4, [5, 6]]]
    [1, 2, ["a", 4, [5, 6]]]
    */
    

    原始数组中的任何其他对象都将通过引用复制

    【讨论】:

    • 您可以检查数组中每个对象上是否存在clone 方法,如果存在则调用它来克隆对象。这将处理数组的递归,并允许任何其他具有克隆方法的对象也可以被深度复制。
    • 它不能正确克隆这样的东西:var a = [[1,2],[3,4]];