ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript配列のディープコピー解析

JavaScript配列のディープコピー解析

高洛峰
高洛峰オリジナル
2016-12-08 10:32:211591ブラウズ

JavaScript の場合、配列は参照型です。concat やスライスなどの関数は浅いコピーであるため、配列をコピーする場合はよく考える必要があります。つまり、2 次元配列の場合、concat を使用してコピーすると、新しい配列を変更すると古い配列も変更されます。

そこで、グループのディープ コピーを支援するディープ コピー関数を作成したいと思いました。

通常、代入は「=」を使用して実現できます。ただし、配列、オブジェクト、関数などの参照型データの場合、このシンボルは使いにくいです。

1. 配列の単純なコピー

1.1 単純なトラバーサル

最も単純で最も基本的な方法は、当然ループ処理です。例:

JavaScript

function array_copy(arr) {
var out = [], i, len;
if (out[i] instanceof Array === false){
return arr;
}
for (i = 0, len = arr.length; i < len; i++) {
if (out[i] instanceof Array){
out[i] = deepcopy(arr[i]);
} else {
out[i] = arr[i];
}
};
return a;
}
//测试
var arr1 = [1, 2, 3, 4],
arr2 = array_copy(arr1);
console.log(arr1, arr2);
arr2[2] = 10;
console.log(arr1[2], arr2[2]);
function array_copy(arr) {
var out = [], i, len;
if (out[i] instanceof Array === false){
return arr;
}
for (i = 0, len = arr.length; i < len; i++) {
if (out[i] instanceof Array){
out[i] = deepcopy(arr[i]);
} else {
out[i] = arr[i];
}
};
return a;
}
//测试
var arr1 = [1, 2, 3, 4],
arr2 = array_copy(arr1);
console.log(arr1, arr2);
arr2[2] = 10;
console.log(arr1[2], arr2[2]);

1.2 代替コピーの実装

面接の質問でよく登場するトリックは、slice メソッドまたは concat メソッドを使用することです。例:

JavaScript

var arr1 = [1, 2, 3, 4],
arr2 = arr1.slice(0),
arr3 = arr1.concat();
console.log(arr1, arr2, arr3);
arr2[2] = 10;
arr3[2] = 11;
console.log(arr1[2], arr2[2], arr3[2]);
var arr1 = [1, 2, 3, 4],
arr2 = arr1.slice(0),
arr3 = arr1.concat();
console.log(arr1, arr2, arr3);
arr2[2] = 10;
arr3[2] = 11;
console.log(arr1[2], arr2[2], arr3[2]);

2. 配列のディープコピー

通常の 1 次元配列で値が非参照型の場合は、上記の方法を使用しても問題ありません。それ以外の場合は、もっと面倒です。ディープコピーでは、配列値がさまざまな参照型である場合を考慮する必要があります。

2.1 JSON メソッド

JSON.stringify(array) を使用してから、JSON.parse() を使用します。例:

JavaScript

var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
arr2 = JSON.parse(JSON.stringify(arr1));
console.log(arr1, arr2);
arr2[1] = 10;
arr2[3].a = 20;
console.log(arr1[1], arr2[1]);
console.log(arr1[3], arr2[3]);
var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
arr2 = JSON.parse(JSON.stringify(arr1));
console.log(arr1, arr2);
arr2[1] = 10;
arr2[3].a = 20;
console.log(arr1[1], arr2[1]);
console.log(arr1[3], arr2[3]);

このメソッドには、古いブラウザとの互換性の問題があります。互換性が実際に必要な場合は、次の互換性ファイルを導入できます:

https://github.com/douglascrockford/JSON-js/blob/master/json2.js

注: 配列値が関数の場合、上記の方法はまだ機能しません。

2.2 ディープコピーの完全実装

多次元配列の入れ子や、配列の値がオブジェクトである状況を考慮すると、以下のようなプロトタイプ拡張が可能です(もちろん通常通りに書くことも可能です)関数、プロトタイプ拡張は推奨されません) :

JavaScript

Object.prototype.clone = function () {
var o = {};
for (var i in this) {
o[i] = this[i];
}
return o;
};
Array.prototype.clone = function () {
var arr = [];
for (var i = 0; i < this.length; i++)
if (typeof this[i] !== &#39;object&#39;) {
arr.push(this[i]);
} else {
arr.push(this[i].clone());
}
return arr;
};
//测试1 Object
var obj1 = {
name: &#39;Rattz&#39;,
age: 20,
hello: function () {
return "I&#39;m " + name;
}
};
var obj2 = obj1.clone();
obj2.age++;
console.log(obj1.age);
//测试2 Array
var fun = function(log) {console.log},
arr1 = [1, 2, [3, 4], {a: 5, b: 6}, fun],
arr2 = arr1.clone();
console.log(arr1, arr2);
arr2[2][1]= &#39;Mike&#39;;
arr2[3].a = 50;
arr2[4] = 10;
console.log(arr1, arr2);
Object.prototype.clone = function () {
var o = {};
for (var i in this) {
o[i] = this[i];
}
return o;
Array.prototype.clone = function () {
var arr = [];
for (var i = 0; i < this.length; i++)
if (typeof this[i] !== &#39;object&#39;) {
arr.push(this[i]);
} else {
arr.push(this[i].clone());
}
return arr;
//测试1 Object
var obj1 = {
name: &#39;Rattz&#39;,
age: 20,
hello: function () {
return "I&#39;m " + name;
}
var obj2 = obj1.clone();
console.log(obj1.age);
//测试2 Array
var fun = function(log) {console.log},
arr1 = [1, 2, [3, 4], {a: 5, b: 6}, fun],
arr2 = arr1.clone();
console.log(arr1, arr2);
arr2[2][1]= &#39;Mike&#39;;
arr2[3].a = 50;
arr2[4] = 10;
console.log(arr1, arr2);

2.3 jQueryのextendメソッドを使う

jQueryを使用している場合、最も簡単な方法はextendプラグインメソッドを使用することです。例:

JavaScript

var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
arr2 = $.extend(true, [], arr1);
console.log(arr1, arr2);
arr2[1] = 10;
console.log(arr1, arr2);
var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
arr2 = $.extend(true, [], arr1);
console.log(arr1, arr2);
arr2[1] = 10;
console.log(arr1, arr2);


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。