对象的浅拷贝和深拷贝

2019-11-05  本文已影响0人  Rui___

对象的深拷贝和浅拷贝

//拷贝出来的结果 和以前没关系 叫深拷贝
let school = { name: "王星星", age: 10 };
let my = { address: "回龙观" };
let newObj = { ...school, ...my };
console.log(newObj);//{ name: '王星星', age: 10, address: '回龙观' }
console.log(school)//{ name: '王星星', age: 10 }
newObj.age=20;//
console.log(newObj)//{ name: '王星星', age: 20, address: '回龙观' }
console.log(school)//{ name: '王星星', age: 10 }

//...如果用的是多层对象 那就是浅拷贝
let school = { name: "王星星", age: 10 ,a:{b:2}};
let my = { address: "回龙观" };
let newObj = { ...school, ...my };
console.log(newObj);//
console.log(school)//
newObj.a.b=20;//
console.log(newObj)//
console.log(school)//

如何 实现一个深拷贝 递归拷贝
1、外部库 lodash =>cloneDeep
2、自实现

// 1) 怎么判断数据的类型
// typeof object Array
// Object.prototype.toString.call()
// instanceof 可以判断类型 判断是谁的实例
// constructor 构造函数

const deepClone = (value ,hash = new WeakMap) => {
    if(value == null) return value; // 排除掉null 和undefine 的情况
    if(typeof value !== 'object') return value; // 这里包含了函数类型
    if(value instanceof RegExp) return new RegExp(value);
    if(value instanceof Date) return new Date(value);
    // .....
    // 拷贝的人可能是一个对象 或者是一个数组 (循环)  for in 
    let instance = new value.constructor; // 根据当前属性构造一个新的实例
    if(hash.has(value)){ // 先去hash中查看一下是否存在过 ,如果存在就把以前拷贝的返回去 
        return hash.get(value); // 返回已经拷贝的结果
    }
    hash.set(value,instance);// 没放过就放进去
    // 用一个对象来记忆
    for(let key in value){ // 一层
        if(value.hasOwnProperty(key)){ // 将hash 继续向下传递 保证这次拷贝能拿到以前拷贝的结果
            instance[key] = deepClone(value[key],hash); // 产生的就是一个新的拷贝后的结果
        }// 过滤掉原型链上的属性
    }
    return instance
};


let school = {
    name: "老肥",
    age: 10,
    a: { b: {c:45} },
    fn: () => {},
    c: undefined,
    reg: /\d+/
  };

  let obj1 = deepClone(school);
  obj1.a.b.c="王菲"
  console.log(obj1);
  console.log(school)
上一篇 下一篇

猜你喜欢

热点阅读