1. 程式人生 > 實用技巧 >JS深拷貝和淺拷貝

JS深拷貝和淺拷貝

淺拷貝

當我們拷貝物件時,如果物件的屬性值是一個引用資料型別,子物件拷貝的只是父物件的地址,當子物件訪問該屬性值時,會根據這個地址去找到父物件指向的堆記憶體,兩者的屬性值會指向同一記憶體空間。

var a={key1:"11111"}
function Copy(p){
   var c ={};
   for (var i in p){
      c[i]=p[i]
   }    
   return c;
}
a.key2 = ["小輝","小輝"]
var b = Copy(a);
b.key3 = "33333"
alert(b.key1)//11111
alert(b.key3)//33333
alert(a.key3);//undefined
b.key2.push("大輝")
alert(a.key2);//小輝,小輝,大輝

實現淺拷貝常見的方法

//ES6實現淺拷貝的方法
var a = {name:"暖風"}
var b= Object.assign({},a);
b.age = 18;
console.log(a.age);//undefined
----------------------------------
//陣列
var a = [1,2,3];
var b = a.slice();
b.push(4);
b//1,2,3,4
a//1,2,3
----------------------------------
var
a = [1,2,3]; var b = a.concat(); b.push(4); b//1,2,3,4 a//1,2,3 ---------------------------------- var a = [1,2,3]; var b = [...a] b//1,2,3,4 a//1,2,3

深拷貝

或許以上並不是我們在實際編碼中想要的結果,我們不希望父子物件之間產生關聯,那麼這時候可以用到深拷貝。既然屬性值型別是陣列和或象時只會傳址,那麼我們就用遞迴來解決這個問題,把父物件中所有屬於物件的屬性型別都遍歷賦給子物件即可。

var a={key1:"11111"}
function Copy(p,c){
   
var c =c||{}; for (var i in p){ if(typeof p[i]==="object"){ c[i]=(p[i].constructor ===Array)?[]:{} Copy(p[i],c[i]); }else{ c[i]=p[i] } } return c; } a.key2 = ["小輝","小輝"] var b = {} b = Copy(a,b); b.key2.push("大輝"); b.key2//小輝,小輝,大輝 a.key2//小輝,小輝