# 浅拷贝

浅拷贝是只拷贝一层,并且对象也只是拷贝对象的内存地址

因为深层次的拷贝必然是对对象的拷贝,所以也是拷贝的内存地址,换句话说,更改新对象深层属性老对象也会改变

function shallowClone(obj) {
  let newObj = {}
  for (let key in obj) {
    // 会忽略掉那些从原型链上继承到的属性
    if (obj.hasOwnProperty(key)) {
      newObj[key] = obj[key]
    }
  }
  return newObj
}

hasOwnProperty 会忽略掉那些从原型链上继承到的属性

o = new Object();
o.prop = 'exists';
o.hasOwnProperty('prop');             // 返回 true
o.hasOwnProperty('toString');         // 返回 false
o.hasOwnProperty('hasOwnProperty');   // 返回 false

# 深拷贝

深拷贝可以拷贝深层次的属性,深拷贝是新开栈,两个对象指向不同的地址

使用WeakMap保存属性,WeakMap的属性是弱引用,在不使用的情况下会被垃圾回收机制回收

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); // weakmap存储对象会产生一个新的引用,所以修改原对象不会影响到weakmap
let cloneObj = new obj.constructor();
// 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
hash.set(obj, cloneObj);
for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    // 实现一个递归拷贝
    // console.log('value', key, deepClone(obj[key], hash))
    cloneObj[key] = deepClone(obj[key], hash);
  }
}
return cloneObj;
}