美文网首页
js 最牛深拷贝实现

js 最牛深拷贝实现

作者: 乐宝呗 | 来源:发表于2023-03-23 08:56 被阅读0次

    最近发现了一款深拷贝的最牛实现,比以往的都要新颖,copy下来 以备不时之需。

    • 针对能够遍历对象的不可枚举属性以及 Symbol 类型,我们可以使用 Reflect.ownKeys 方法;
    • 当参数为 Date、RegExp 类型,则直接生成一个新的实例返回;
    • 利用 Object 的 getOwnPropertyDescriptors 方法可以获得对象的所有属性,以及对应的特性,顺便结合 Object.create 方法创建一个新对象,并继承传入原对象的原型链;
    • 利用 WeakMap 类型作为 Hash 表,因为 WeakMap 是弱引用类型,可以有效防止内存泄漏(你可以关注一下 Map 和 weakMap 的关键区别,这里要用 weakMap),作为检测循环引用很有帮助,如果存在循环,则引用直接返回 WeakMap 存储的值
    const isComplexDataType = obj => (typeof obj === 'object' || typeof obj === 'function') && (obj !== null)
    
    const deepClone = function (obj, hash = new WeakMap()) {
      if (obj.constructor === Date) {
        return new Date(obj)       // 日期对象直接返回一个新的日期对象
      }
    
      if (obj.constructor === RegExp){
        return new RegExp(obj)     //正则对象直接返回一个新的正则对象
      }
    
      //如果循环引用了就用 weakMap 来解决
      if (hash.has(obj)) {
        return hash.get(obj)
      }
      let allDesc = Object.getOwnPropertyDescriptors(obj)
    
      //遍历传入参数所有键的特性
      let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)
    
      // 把cloneObj原型复制到obj上
      hash.set(obj, cloneObj)
    
      for (let key of Reflect.ownKeys(obj)) { 
        cloneObj[key] = (isComplexDataType(obj[key]) && typeof obj[key] !== 'function') ? deepClone(obj[key], hash) : obj[key]
      }
      return cloneObj
    }
    
    

    验证例子

    // 下面是验证代码
    let obj = {
      num: 0,
      str: '',
      boolean: true,
      unf: undefined,
      nul: null,
      obj: { name: '我是一个对象', id: 1 },
      arr: [0, 1, 2],
      func: function () { console.log('我是一个函数') },
      date: new Date(0),
      reg: new RegExp('/我是一个正则/ig'),
      [Symbol('1')]: 1,
    };
    Object.defineProperty(obj, 'innumerable', {
      enumerable: false, value: '不可枚举属性' }
    );
    obj = Object.create(obj, Object.getOwnPropertyDescriptors(obj))
    obj.loop = obj    // 设置loop成循环引用的属性
    let cloneObj = deepClone(obj)
    cloneObj.arr.push(4)
    console.log('obj', obj)
    console.log('cloneObj', cloneObj)
    
    

    效果:


    image.png

    原创链接:https://juejin.cn/post/7205527600700604477

    相关文章

      网友评论

          本文标题:js 最牛深拷贝实现

          本文链接:https://www.haomeiwen.com/subject/enqirdtx.html