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

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

  1. 浅拷贝:

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

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

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

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

      以下是一个示例来说明:

      js 复制代码
      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' } }

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

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

  2. 深拷贝:

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

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

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

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

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

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

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

        js 复制代码
        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;
        }
      2. 使用 JSON 序列化和反序列化:通过将对象转换为 JSON 字符串,然后再将其转换回对象,可以实现深拷贝。这种方法适用于大多数普通对象,但它无法处理函数、正则表达式和特殊对象类型。

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

        js 复制代码
        const obj = { foo: 'bar' };
        const clonedObj = structuredClone(obj);
        
        console.log(clonedObj); // { foo: 'bar' }

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

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

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

相关推荐
恋猫de小郭1 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端