js手写一个深拷贝

40 阅读1分钟

处理了一些边界情况,解决了循环引用的问题,但是Symbol的拷贝逻辑没写

let obj = {
      name: "ssl",
      age: 18,
      date: new Date(),
      regexp: new RegExp(),
      frineds: [
        {name:"zzq", age:25},
        {name:"bff", age:3}
      ],
      address: {
        name: "广东",
        code: 518000
      },
      eating(){
        console.log("吃饭");
      },
}

// 制造一个循环引用
obj.cloneObj = obj 
let cloneObj = deepClone(obj)
console.log('cloneObj: ', cloneObj);

function deepClone(obj, map = new WeakMap()){
      // 这些类型的直接返回obj
      if(typeof obj !== 'object' ||
         obj === null ||
         obj instanceof Date ||
         obj instanceof RegExp
      ) return obj

      // 判断传进来的值是数组还是对象
      let cloneObj = Array.isArray(obj) ? [] : {}

      // 判断是否循环引用,循环了这直接返回映射的地址,防止回调地狱
      if(map.get(obj)) return map.get(obj)
      map.set(obj, cloneObj)

      // 数组也可以遍历
      Object.keys(obj).forEach(key => {
        cloneObj[key] = deepClone(obj[key], map)
      });

      return cloneObj

    }