1

関数内でクローンを作成しても、ネストされた配列が変更されます。a配列を保存する最も効率的な方法は何ですか? JSBinはこちら

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);
4

2 に答える 2

0

.slice は「ディープ」コピーを行いません。'a' の各要素は配列 iteslf であるため、'a' の要素は内部の、それ以外の場合は匿名の要素への参照です。

配列「l」は、参照のコピーを保持します。コピーされた参照は、それらが参照する同じ「オブジェクト」を指します。

于 2013-07-29T15:10:27.260 に答える
0

あなたのコードは、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] "関数内、変更前" [2, 3, 1, 5, 2, 3, 7, 2] "関数内、変更後変更" [2, 17, 1, 5, 2, 3, 7, 2] "通話後" [2, 3, 1, 5, 2, 3, 7, 2]

それが 2D 配列であるという事実があなたを悩ませています。2D JavaScript 配列の複製に関するこのスタック オーバーフロー応答を確認してください。

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]] "関数内、変更前" [[2, 3], [1, 5, 2], [ 3, 7, 2]] "関数内、変更後" [[2, 3], [1, 2], [3, 7, 2]] "呼び出し後" [[2, 3], [1, 5 、2]、[3、7、2]]

于 2013-07-29T15:25:58.887 に答える