对象的深拷贝和浅拷贝和拷贝方法

  我们知道对象在内存中分两块存储,引用地址存放在栈内存,而本身的数据是存放在堆内存

 

  所以我们区别是否是深拷贝或者浅拷贝可以观察修改拷贝后的对象的属性值之后原对象的该属性值是否改变;

 

  浅拷贝的对象和原对象都指向同一块引用空间,只是引用地址不同罢了; 如图所示

 

  下面进行深拷贝和浅拷贝的方法总结;

 

    1 ,浅拷贝方法

      ① 使用es6的扩展运算符

    

let obj = {
  a: 1,
  b :[1,2,3],
  c: {
     name: 'qq',
     age: 12  
    }  
}

let  o = {...obj};

o.c.name ='zq';
// 此时源对象也会改变

  ② 数组slice 进行数组浅拷贝

  

let arr = [1,3,4]
let newarr = arr.slice()

 2.  深拷贝方法

   ① JSON.parse(JSON.stringfy(obj)) 进行深拷贝  对象里面的函数会丢失,同时undefined 也会丢失,正则等也会丢失

   

let obj = {
a:1,
b:[1,2,3],
c:{name: 'qq',age: 12},
d: null,
e: undefined,
f: /\$[a-zA-Z_]+/g
}

 

 

let b = JSON.parse(JSON.stringify(obj));

b 得到 {"a":1,"b":[1,2,3],"c":{"name":"qq","age":12},"d":null,"f":{}}"

  ② 使用递归实现深拷贝

 

function deepClone(obj, hash = new WeakMap()){
    // 判断特殊值
    if(obj == null) return obj; // null undefined 不进行拷贝操作
    if(obj instanceof Date) return new Date(obj)  // 产生了 一个新的日期对象
    if(obj instanceof RegExp) return new RegExp(obj); // 正则对象
    // 对象或者普通值
    if(typeof obj !== 'object') return obj;
    
    if(hash.get(obj)) return hash.get(obj)  // 避免循环引用

    let cloneObj = new obj.constructor; // 通过constructor 获取到obj的构造函数 产生一个新对象 ,可以避免判断值是对象或者数组
    hash.set(obj,cloneObj) // 让生成的克隆对象先放入weakMap中; 
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            cloneObj[key] = deepClone(obj[key],hash);
        }
    }

    return cloneObj;

}

let obj = {name:1, address:{x:10}};
obj.o = obj;
let d = deepClone(obj)
console.log(d,{depth: 10});

 

posted @ 2020-08-15 10:43  大桥默默学  阅读(598)  评论(0编辑  收藏  举报