项目图片

前端的浅拷贝和深拷贝,与实现

weiping8/8/20265831

  • 浅拷贝

    • 只复制对象的第一层,对值类型就拷贝其值,对嵌套引用类型(如对象、数组)就拷贝其引用,仍然与源数据共享内存地址。

    • 特点:修改拷贝对象的嵌套属性会影响原对象。

    • // 第一种
      const obj = { a: 1, nested: { b: 2 } };
      const shallowCopy = Object.assign({}, obj);
      // 第二种
      const arr = [1, 2, { c: 3 }];
      const arrCopy = [...arr];
      // 第三种
      function shallowClone(obj) {
        const newObj = {};
        for (let key in obj) {
          if (obj.hasOwnProperty(key)) newObj[key] = obj[key];
        }
        return newObj;
      }
      
  • 深拷贝

    • 递归复制对象的所有层级,生成完全独立的新对象,与原对象无内存关联。

    • 特点:修改对象的任何层级不会影响原对象。

    • // 深拷贝简单实现
      function deepClone(obj, hash = new WeakMap()) {
        if (obj === null || typeof obj !== "object") return obj; // 判断对象类型
        if (hash.has(obj)) return hash.get(obj); // 解决循环引用
        const clone = new obj.constructor(); // 根据构造函数创建对象,这样就不需要判断了
        hash.set(obj, clone); // 设置对象到 WeakMap
        for (let key in obj) {
          // 遍历对象属性
          if (obj.hasOwnProperty(key)) {
            // 判断是否原型链上方法
            clone[key] = deepClone(obj[key], hash); // 递归设置新对象属性
          }
        }
        return clone; // 返回克隆对象
      }
      // 要点一: 那么我们为什么需要 obj.hasOwnProperty() ==>'嗨丝哦坡婆挺' ? 因为要区分,自身属性与继承属性,避免原型链污染