什麼是深拷貝?什麼是淺拷貝?如何實現深拷貝?
阿新 • • 發佈:2020-09-07
深拷貝和淺拷貝是針對引用型別的
淺拷貝:
簡單來說就是一個物件B複製另一個物件A,當改變B物件的值是A物件的值也隨之改變。
舉個例子
var obj1={a:1,b:5,c:3}; var obj2=obj1; obj2.b=2; console.log(obj1.b); //2 console.log(obj2.b); //2
可以看到兩個物件的值都被修改了。
淺拷貝:就是拷貝物件的引用,而不深層次的拷貝物件的值,多個物件指向堆記憶體中的同一物件,,任何一個修改都會是使得所有物件的值被修改,因為它們公用一條資料。
深拷貝:
簡單來說就是一個物件B複製另一個物件A,當改變B物件的值是A物件的值不會改變 。
舉個例子:
var a=2; var b=a; b=3; console.log(a);//2 console.log(b);//3
以上例子說明兩個變數使用的是獨立的資料。對於基本資料型別來說不存在深拷貝、淺拷貝。直接賦值就是深拷貝。
深拷貝:深拷貝不會拷貝引用型別的引用,拷貝的是引用型別的值,形成一個新的引用型別。
如何實現深拷貝:
①JSON.Stringify(JSON.pare()) 不支援多層引用巢狀,不支援函式Map、Sep等型別的資料
var obj1={a:1,b:5,c:3}; var obj2=JSON.Stringify(JSON.parse(obj1)); obj2.b=2; console.log(obj1.b); //5 console.log(obj2.b); //2
②展開運算子 ...
var obj1={a:1,b:5,c:3}; var obj2=(...obj1) obj2.b=2; console.log(obj1.b); //5 console.log(obj2.b); //2
③Object.asssign(target,sourse)
var obj1={a:1,b:5,c:3}; var obj2=Object.assign({},obj1) obj2.b=2; console.log(obj1.b); //5 console.log(obj2.b); //2
④深拷貝函式,遞迴
// target 要拷貝的物件 function deepClone(target){ //定義一個拷貝物件 let result; // 判斷拷貝目標是不是Object物件 if(typeof target==='object'){ // 判斷是否是陣列型別 if(Array.isArray(target)){ // 定義為陣列 result=[]; for(let i in target){ result.push(deepClone(target[i])); } }else if(target===null){ // 直接賦值 result=null; }else if(target.constructor===RegExp){ // 直接賦值 result=target; // 不是特殊的物件 }else{ result={}; for(let i in target){ // 遞迴 result[i]=deepClone(target[i]); } } // 基本資料型別 直接賦值 }else{ result=target; } return result; }
var obj1={
a:{z:1,c:null},
b:[1,2,3,5],
c:function(){console.log(this.a)}
}
var obj2=deepClone(obj1);
console.log(obj2);
obj2.b[0]=2;
obj2.a[0]=2;
console.log(obj1.a)
console.log(obj2.a)
console.log(obj1.b)
console.log(obj2.b)
console.log(obj2.c())