數組和對象的拷貝方式有很多,此處只針對擴展運算符...對數組和對象的深拷貝方式進行說明。
還介紹一篇深拷貝的方法 深拷貝的終極探索用擴展運算符深拷貝數組:
直接粘貼代碼:
let arr = [1, 2, 3, 4, 5, 6];
let arr1 = [...arr];
arr1.push(7);
console.log(arr); //[1, 2, 3, 4, 5, 6]
console.log(arr1); //[1, 2, 3, 4, 5, 6, 7]
當數組是一維數組時,擴展運算符可以進行完全深拷貝,改變拷貝后數組的值並不會影響拷貝源的值。
但是,當數組為多維時:
let arr = [1, 2, 3, 4, 5, 6, [1, 2, 3]];
let arr1 = [...arr];
arr1.push(7);
arr1[arr1.length - 2][0] = 100;
console.log(arr); //[1, 2, 3, 4, 5, 6,[100, 2, 3]]
console.log(arr1); //[1, 2, 3, 4, 5, 6, [100, 2, 3],7]
由上可見,我們不難發現當改變拷貝后數組中第二層數組的值時,arr1arr1.length - 2 = 100;拷貝前數組第二層數組的值也跟着改變了。
對象同理:
當對象只有一層時:
let obj = {
name: "Wawa",
age: 13,
gender: "female"
};
let obj1 = {...obj
};
obj1.height = 165;
console.log(obj);//{name: "Wawa", age: 13, gender: "female"}
console.log(obj1);//{name: "Wawa", age: 13, gender: "female", height: 165}
可以用擴展運算符進行完全深拷貝。
但當對象有多層時:
let obj = {
name: "Wawa",
age: 13,
gender: "female",
hobby: {
a: 'Chinese',
b: 'Math',
c: 'English'
}
};
let obj1 = {...obj
};
obj1.hobby.a = "PE";
console.log(obj); //{name: "Wawa", age: 13, gender: "female",hobby:{a: "PE", b: "Math", c: "English"}}
console.log(obj1); //{name: "Wawa", age: 13, gender: "female", ,hobby:{a: "PE", b: "Math", c: "English"},height: 165}
擴展運算符並不能打散第二層對象的值,且無法對其進行深拷貝,拷貝前和拷貝后第二層對象的引用地址仍然是同一個,一方改變,另一方也改變。
結論:用擴展運算符對數組或者對象進行拷貝時,只能擴展和深拷貝第一層的值,對於第二層極其以后的值,擴展運算符將不能對其進行打散擴展,也不能對其進行深拷貝,即拷貝后和拷貝前第二層中的對象或者數組仍然引用的是同一個地址,其中一方改變,另一方也跟着改變。
另外有一個疑問,官方說用Object.assign()拷貝時是淺拷貝,可無論我怎么操作都是深拷貝的效果,望大家指出理解錯誤的地方,此處貼上測試的demo:
let obj3 = {
name: "Gucci",
age: 13,
gender: "female",
hobby: {
a: 'Chinese',
b: 'Math',
c: 'English'
}
};
let obj4 = Object.assign({}, obj3);
obj4.hobby.a = "Math";
obj3.age = 1000;
console.log(obj3);
console.log(obj4.age);
無論是一層還是二層,改變拷貝之后屬性的值,拷貝前對象中的任何值並沒有發生改變,且互不影響,這不是深拷貝嗎???