首頁 > web前端 > js教程 > 主體

javascript數組深度複製詳解

大家讲道理
發布: 2016-11-07 16:36:54
原創
1358 人瀏覽過

對於javascript而言,數組是引用類型,如果要想複製一個數組就要動腦袋想想了,因為包括concat、slice在內的函數,都是淺層複製。也就是說,對於一個二維數組來說,用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 或 contcat 方法實作。範例:

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. 陣列的深度複製

普通的一維數組且值為非引用型,使用上述方法是沒有問題的,否則就比較麻煩了。深度複製需要考慮數組值為各種引用類型的情況。

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);
登入後複製
相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!