(前端手撕)4. 手撕深拷贝

手撕深拷贝

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);
    let cloneObj = new obj.constructor();
    // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身,这样就不用
    // 针对数组创建[],针对对象创建{}

    // 记录引用关系
    hash.set(obj, cloneObj);
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        // 实现一个递归拷贝
        cloneObj[key] = deepClone(obj[key], hash);
      }
    }
    return cloneObj;
  }
  let obj = { name: 1, address: { x: 100 } };
  obj.o = obj; // 对象存在循环引用的情况
  let d = deepClone(obj);
  obj.address.x = 200;
  console.log(d);
全部评论

相关推荐

我即大橘:耐泡王
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务