递归深拷贝

111 阅读1分钟
function deepClone(obj,hash = new WeakMap()){
          if(obj == null) return obj;
          if(obj instanceof Date) return new Date(obj);
          if(obj instanceof RegExp) return new RegExp(obj);
          if(typeof obj !== 'object') return  obj;
          if(hash.has(obj)) return hash.get(obj);
          let cloneObj = new obj.constructor;
          hash.set(obj,cloneObj);
          for(let key in obj){
            if(obj.hasOwnProperty(key)){
              cloneObj[key] = deepClone(obj[key],hash);
            }
          }
          return cloneObj;
 }

WeakMap是弱链接 Map不是弱链接 比如

    let obj  = { name: 123 };
    let m = new Map();
    m.set(obj, '1234');
    obj = null;
    这种情况下obj依然被m引用着不会被v8销毁
    let obj  = { name: 123 };
    let m = new WeakMap();
    m.set(obj, '1234');
    obj = null;
    WeakMap就会被销毁,并且WeakMap只能以对象为键

接下来说一说object.defineproperty 里面有一个writable设置为true,就表示可以修改属性,但是一旦设置get和set方法后, 就不能设置writable,不然会报错 通过这个方式可以看出vue的数据劫持怎么做的

1632354942(1).png

1632355198(1).png

所以在vue中数据劫持就是通过这种方式,而且在更新视图必须是data中存在的值,如果data中不存在,那么不会导致视图刷新,新设置的值没有get 和 set,就算修改数组的索引值也可以导致视图刷新

1632356170(1).png