js拷贝(浅拷贝,深拷贝)

16、js拷贝(浅拷贝,深拷贝)

原生方法:

实现浅拷贝的方法

1、使用Object.assign():
let shallowCopy = Object.assign({
    
    },originalObject);
2、使用Spread运算符:
let shallowCopy = {
    
     ...originalObject };
3、使用for……in 循环:
let shallowCopy = {
    
    };
for (let key in originalObject) {
    
    
  shallowCopy[key] = originalObject[key];
}

实现深拷贝的方法

使用JSON.parse()和JSON.stringify()
let deepCopy = JSON.parse(JSON.stringify(originalObject));
  • 源对象中存在函数
  • 源对象存在循环引用
  • 源对象中存在Map、Set数据类型

出现上述情况将会导致严重后果,上述方法会自动忽略

手写深拷贝函数

function deepClone(obj) {
    
    
    // 如果该对象不是对象(即为基本数据类型),则直接返回该值
    if (typeof obj != "object") {
    
    
        return obj;
    }
    // 如果该对象是数组,则创建一个空数组;否则创建一个空对象
    let res = Array.isArray(obj) ? [] : {
    
    };
    // 遍历该对象的属性
    for (let key in obj) {
    
    
      // 如果该属性是该对象的自身属性(即不是继承自原型链的属性)
      if (obj.hasOwnProperty(key)) {
    
    
        // 将该属性的值复制一份
        res[key] = deepClone(obj[key]);
      }
    }
    // 返回复制的对象
    return res;
}
    //测试
    let obj = {
    
    
        a: 1,
        b: [1, 2, 3],
        c: {
    
    
            d: 1
        }
    }
    obj.self = obj;
    console.log(copyObj);

上述方法遇到循环访问将会无限递归

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TIh6kS7R-1677566744079)(C:\Users\tony5\OneDrive\笔记\前端错题笔记\错题笔记.assets\image-20230228144405888.png)]

function deepClone(obj) {
    
    
    // 创建一个 Map 对象,用来存储已经复制的对象
    let map = new Map();
    // 定义 doClone 函数,用于递归复制对象
    function doClone(obj) {
    
    
      // 如果该对象不是对象(即为基本数据类型),则直接返回该值
      if (typeof obj != "object") {
    
    
        return obj;
      }
      // 如果该对象已经被复制过,则直接返回复制的对象
      if (map.has(obj)) return map.get(obj);
      // 如果该对象是数组,则创建一个空数组;否则创建一个空对象
      let res = Array.isArray(obj) ? [] : {
    
    };
      //将创建的对象放入Map中
      map.set(obj, res);
      // 遍历该对象的属性
      for (let key in obj) {
    
    
        // 如果该属性是该对象的自身属性(即不是继承自原型链的属性)
        if (obj.hasOwnProperty(key)) {
    
    
          // 将该属性的值复制一份
          res[key] = doClone(obj[key]);
        }
      }
      // 返回复制的对象
      return res;
    }
    // 返回递归调用 doClone 函数的结果,即深拷贝后的对象
    return doClone(obj);
  }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_61696809/article/details/129261565
今日推荐