• 关于深拷贝和浅拷贝你需要了解的内容


    深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在复制对象或数据结构时使用的两种不同的策略,它们的主要区别在于复制后新旧对象之间的关系以及对嵌套对象的处理方式。

    1. 浅拷贝

      • 浅拷贝创建一个新对象,并将原始对象的属性值复制到新对象中。

      • 浅拷贝通常是通过复制引用来实现的,例如使用扩展运算符(...)或 Object.assign() 方法。

      • 新对象和原始对象共享相同的引用类型属性(如对象、数组),即新对象中的引用类型属性仍然引用原始对象中的相同对象。

      • 当修改原始对象的引用类型属性时,新对象中的对应属性也会受到影响。同样地,修改新对象的引用类型属性时,原始对象中的对应属性也会受到影响

        以下是一个示例来说明:

        const obj = { foo: 'bar', nested: { prop: 'value' } };
        const clonedObj = { ...obj };
        
        console.log(obj); // { foo: 'bar', nested: { prop: 'value' } }
        console.log(clonedObj); // { foo: 'bar', nested: { prop: 'value' } }
        
        // 修改新对象的引用类型属性
        clonedObj.foo = 'baz';
        clonedObj.nested.prop = 'new value';
        
        console.log(obj); // { foo: 'bar', nested: { prop: 'new value' } }
        console.log(clonedObj); // { foo: 'baz', nested: { prop: 'new value' } }
        
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13

        在上述示例中,修改了新对象 clonedObj 的引用类型属性 nested.prop 的值,结果原始对象 obj 中的对应属性也发生了变化。这是因为它们引用的是同一个嵌套对象。

        所以,在浅拷贝中,无论是修改原始对象的引用类型属性还是修改新对象的引用类型属性,双方都会受到影响,因为它们共享相同的引用。如果需要避免这种相互影响,可以使用深拷贝来创建完全独立的对象副本。

    2. 深拷贝:

      • 深拷贝创建一个完全独立的新对象,新对象和原始对象没有任何引用关系。

      • 所有的属性值都被复制到新对象中,包括基本类型和引用类型属性。

      • 当修改原始对象的引用类型属性时,新对象中的对应属性不会受到影响。

      • 深拷贝通常需要递归地复制嵌套对象,确保每个对象都是独立的副本。

      • 深拷贝可以通过手动递归复制、使用第三方库(如 Lodash 的 cloneDeep 方法)或使用 JSON 序列化和反序列化来实现

      • 在 JavaScript 中,有几种方法可以实现对象的深拷贝。下面是其中一些常见的方法:

        1. 手动递归复制:这是一种基本的深拷贝方法,可以递归地复制对象和嵌套的属性。可以通过遍历对象的属性并递归地进行复制来实现。但是,这种方法需要处理循环引用的情况,并且在处理特殊对象类型时可能会有一些问题。

          function deepCopy(obj) {
            if (typeof obj !== 'object' || obj === null) {
              return obj;
            }
          
            let copy = Array.isArray(obj) ? [] : {};
          
            for (let key in obj) {
              if (obj.hasOwnProperty(key)) {
                copy[key] = deepCopy(obj[key]);
              }
            }
          
            return copy;
          }
          
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
        2. 使用 JSON 序列化和反序列化:通过将对象转换为 JSON 字符串,然后再将其转换回对象,可以实现深拷贝。这种方法适用于大多数普通对象,但它无法处理函数、正则表达式和特殊对象类型。

          function deepCopy(obj) {
            return JSON.parse(JSON.stringify(obj));
          }
          
          
          • 1
          • 2
          • 3
          • 4
        3. structuredClone 是 JavaScript 中的一种深拷贝方法,它可以复制包括对象、数组、函数、日期、正则表达式等在内的各种数据类型,同时还能处理循环引用的情况。structuredClone 主要用于 Web Workers、IndexedDB 和 postMessage 等场景中,用于在不同的上下文之间传递数据副本。以下是使用 structuredClone 方法进行深拷贝的示例:

          const obj = { foo: 'bar' };
          const clonedObj = structuredClone(obj);
          
          console.log(clonedObj); // { foo: 'bar' }
          
          
          • 1
          • 2
          • 3
          • 4
          • 5

          需要注意的是,structuredClone 方法是浏览器提供的内置方法,在纯 JavaScript 环境中并不可用。此外,它也无法处理一些特殊对象类型,如 DOM 节点、函数的闭包等。

          如果你在浏览器环境中使用 structuredClone 方法,请确保在支持的浏览器版本中使用,并注意其适用范围和限制。

    总结起来,浅拷贝只复制对象的第一层属性,并共享引用类型属性,而深拷贝复制了所有层级的属性,并且新对象和原始对象完全独立,没有引用关系。根据具体的需求和场景,选择适合的拷贝方式是很重要的。需要注意的是,深拷贝可能会更耗费内存和计算资源,特别是在处理大型或嵌套层级深的对象时。

  • 相关阅读:
    【学习笔记】ARC150/ARC151
    springboot整合SSE
    sql语句之多表查询
    数据结构 | 带头双向循环链表【无懈可击的链式结构】
    Google Earth Engine-06(GEE操作方法)
    【规范】Git分支管理,看看我司是咋整的
    【C++11】C++11新增语法特性 右值引用/移动语义/完美转发
    一套简单的机器人短途路径规划算法
    Yalmip使用教程(6)-将约束条件写成矩阵形式
    Python 页面解析:Beautiful Soup库的使用
  • 原文地址:https://blog.csdn.net/qq_43720551/article/details/133721057