常用的js數組複製(淺拷貝和深拷貝)
在js當中,我們常常遇到數組複製的的情況,許多人一般都會使用“=”來直接把一個數組賦值給一個變量,Array是引用類型,如果只是通過 arrayA = arrayB 簡單的賦值,arrayA 和 arrayB 指向的是同一個地址,其實際的值是同一塊東西,舉個例子
let A = [ 1, 2, 3 ]
let B = A
B[0] = 2 // 此時改變B中a的值
console.log(A) // [ 2, 2, 3 ]
console.log(B) // [ 2, 2, 3 ]
此時,A 也跟着改變,我們在實際應用中就容易受影響。這明顯不是我們所想要的結果。所以,我們想要的是兩個互不影響的數組纔對。
情況有兩種,深拷貝以及淺拷貝
一、淺拷貝
(適用於數組並不複雜、即數組中沒有數組嵌套了對象或者數組的情況)
1.直接解構賦值
let A = [ 1, 2, 3 ]
let B = [ ...A ]
2.Object.assign()
let A = [ 1, 2, 3 ]
let B = Object.assign( [], A );
3.concat()
let A = [ 1, 2, 3 ]
let B = A.concat();
4.slice()
// arrayObject.slice(start,end),該方法返回一個新的數組,包含從 start 到 end (不包括該元素)的 arrayObject 中的元素
let A = [ 1, 2, 3 ]
let B = A.slice(0);
上面四種方式,當數組複雜一些就有點問題了,比如說:
let A = [ { a: 1 }, [ 1, 2 ], 3 ];
let B = A.concat();
A[0].a = 2
B[1][0] = 2
B[2] = 2 // 第一層簡單的不會互相影響
console.log(A); // [ { a: 2 }, [ 2, 2 ], 3 ];
console.log(B); // [ { a: 2 }, [ 2, 2 ], 2 ];
5.通用方法(數組或對象),遍歷對象,把屬性和屬性值都放在一個新的對象裏
(參考:https://blog.csdn.net/qq_37268201/article/details/80448848)
var shallowCopy = function (obj) {
// 只拷貝對象
if (typeof obj !== 'object') return;
// 根據obj的類型判斷是新建一個數組還是一個對象
var newObj = obj instanceof Array ? [] : {};
// 遍歷obj,並且判斷是obj的屬性才拷貝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
也就是說數組裏更深層的還是會相互影響,所以我們才需要深拷貝
二、深拷貝
1.通過JSON.stringify轉化成字符串再通過JSON.parse()解析成原數組
let A = [ { a: 1 }, [ 1, 2 ], 3 ];
let B = JSON.parse( JSON.stringify( A ) );
2.利用jQuery的$.extend方法
let A = [ { a: 1 }, [ 1, 2 ], 3 ];
let B = $.extend( true , [] , A ); // 默認爲false,是淺拷貝,true爲深拷貝
3.通用方法(數組或對象),拷貝的時候判斷屬性值的類型,如果是對象,繼續遞歸調用深拷貝函數
(參考:https://blog.csdn.net/qq_37268201/article/details/80448848)
var deepCopy = function(obj) {
// 只拷貝對象
if (typeof obj !== 'object') return;
// 根據obj的類型判斷是新建一個數組還是一個對象
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
// 遍歷obj,並且判斷是obj的屬性才拷貝
if (obj.hasOwnProperty(key)) {
// 判斷屬性值的類型,如果是對象遞歸調用深拷貝
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}
OK,常用的js數組複製就先記錄這些