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//小辉,小辉

 

 

posted @ 2020-11-19 18:40  乘风破浪的哥哥  阅读(323)  评论(0)    收藏  举报