拷贝的艺术:深拷贝与浅拷贝的区别与应用(下)

news2024/12/23 18:49:43

在这里插入图片描述

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6
🍨 阿珊和她的猫_CSDN个人主页
🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》
🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》

文章目录

  • 四、深拷贝和浅拷贝的区别
    • 比较深拷贝和浅拷贝在拷贝对象时的行为
    • 分析深拷贝和浅拷贝对对象引用的影响
  • 五、使用 JavaScript 实现深拷贝和浅拷贝
    • 提供简单的示例代码
  • 六、深拷贝和浅拷贝的优缺点
    • 分析深拷贝和浅拷贝各自的优势和劣势
    • 讨论在实际应用中如何选择使用深拷贝或浅拷贝
  • 七、总结
    • 总结在使用深拷贝和浅拷贝时需要注意的一些问题

四、深拷贝和浅拷贝的区别

比较深拷贝和浅拷贝在拷贝对象时的行为

深拷贝和浅拷贝在拷贝对象时的行为有以下不同:

  • 基础数据类型:对基础数据类型进行赋值。
  • 引用数据类型:
    • 浅拷贝:对引用数据类型进行传递引用,即拷贝的对象和原对象共享同一份内存,修改其中一个对象会影响另一个对象。
    • 深拷贝:对引用数据类型进行创建新对象并复制其内的成员变量,即拷贝的对象和原对象各自拥有独立的内存,修改其中一个对象不会影响另一个对象。

分析深拷贝和浅拷贝对对象引用的影响

深拷贝和浅拷贝对对象引用的影响如下:

  1. 深拷贝:深拷贝会创建一个完全独立于原始对象的新对象。新对象的所有属性和子对象都是独立的副本,与原始对象没有任何关联。修改新对象的属性或子对象不会影响原始对象,反之亦然。

  2. 浅拷贝:浅拷贝只会复制对象的第一层属性,而不复制嵌套对象或引用对象。这意味着新对象和原始对象会共享嵌套对象或引用对象。修改新对象的嵌套属性或引用对象会同时影响原始对象,因为它们实际上是同一个对象。

在使用深拷贝和浅拷贝时,需要根据具体情况选择适当的方式。如果需要确保对象的独立性和数据安全性,通常使用深拷贝。而浅拷贝适用于不需要修改嵌套对象或引用对象的情况,因为它可以节省内存和性能。

需要注意的是,对于一些特殊类型(如函数、循环引用等)的对象,深拷贝可能无法进行或可能引发递归问题。在这种情况下,可能需要使用其他方法来处理对象的复制和引用关系。

五、使用 JavaScript 实现深拷贝和浅拷贝

提供简单的示例代码

以下是使用 JavaScript 实现深拷贝和浅拷贝的示例代码:

  1. 深拷贝:
function deepCopy(source) {
  let target = {};
  for (let key in source) {
    if (source.hasOwnProperty(key)) {
      if (typeof source[key] === 'object') {
        target[key] = deepCopy(source[key]);
      } else {
        target[key] = source[key];
      }
    }
  }
  return target;
}

// 示例用法
const obj1 = { prop1: 'value1', prop2: { subProp: 'subValue' } };
const copiedObj = deepCopy(obj1);

console.log(obj1 === copiedObj);  // false
console.log(obj1.prop2 === copiedObj.prop2);  // false

在上述示例中,deepCopy函数接受一个源对象作为参数,并创建一个新的目标对象。然后,它使用循环遍历源对象的每个属性,并根据属性的类型进行处理。如果属性的值是一个对象,则递归调用deepCopy函数来复制嵌套对象。否则,将属性的值直接复制到目标对象中。

  1. 浅拷贝:
function shallowCopy(source) {
  let target = {};
  for (let key in source) {
    if (source.hasOwnProperty(key)) {
      target[key] = source[key];
    }
  }
  return target;
}

// 示例用法
const obj1 = { prop1: 'value1', prop2: { subProp: 'subValue' } };
const copiedObj = shallowCopy(obj1);

console.log(obj1 === copiedObj);  // false
console.log(obj1.prop2 === copiedObj.prop2);  // true

在上述示例中,shallowCopy函数接受一个源对象作为参数,并创建一个新的目标对象。然后,它使用循环遍历源对象的每个属性,并将属性的值直接复制到目标对象中。然而,对于嵌套对象,浅拷贝只会复制引用,而不是创建新的嵌套对象。

请注意,深拷贝和浅拷贝的区别在于是否复制嵌套对象。深拷贝会递归复制嵌套对象,创建完全独立的副本。而浅拷贝只复制第一层对象,嵌套对象仍然共享引用。在实际应用中,根据需求选择适当的拷贝方式。

六、深拷贝和浅拷贝的优缺点

分析深拷贝和浅拷贝各自的优势和劣势

深拷贝浅拷贝
优势完全独立的副本,不受原始对象影响创建速度快
修改副本不会影响原始对象内存占用较少
可以进行嵌套对象的完全复制在处理大型对象时更高效
劣势创建速度相对较慢修改副本会直接影响原始对象
内存占用较多嵌套对象只有引用而非完全独立的副本
处理大型对象时相对耗时

深拷贝会创建一个原始对象的完全副本,包括对象的所有嵌套对象,不受原始对象的影响。因此,对副本的修改不会影响原始对象。深拷贝适用于需要独立的对象副本的情况,但由于需要复制整个对象,所以创建速度较慢,内存占用也较多,处理大型对象时会相对耗时。

浅拷贝则只复制原始对象的引用,所以副本和原始对象共享嵌套对象。对副本或原始对象的修改会相互影响。浅拷贝的优势在于创建速度快、内存占用较少,特别适用于处理大型对象或需要快速创建副本的情况。但对于涉及嵌套对象的场景,浅拷贝可能会导致引用问题,因为副本只是引用嵌套对象而非拥有完全独立的副本。

讨论在实际应用中如何选择使用深拷贝或浅拷贝

在实际应用中,选择使用深拷贝还是浅拷贝取决于你的具体需求和场景。以下是一些考虑因素:

  1. 对象的嵌套层次:如果对象包含嵌套对象,且你需要独立修改每个嵌套对象,那么深拷贝可能是更好的选择,以确保每个嵌套对象都是独立的副本。

  2. 数据的重要性和安全性:如果数据非常重要,你不希望在操作过程中意外修改原始数据,那么深拷贝可以提供更好的数据安全性。

  3. 性能考虑:如果性能是关键因素,并且对象不包含需要独立修改的嵌套对象,那么浅拷贝可能更适合,因为它的性能通常更好。

  4. 资源消耗:深拷贝会创建完全独立的副本,因此可能会消耗更多的内存资源。如果对象较大或嵌套层次较深,可能会导致内存消耗过高。在这种情况下,浅拷贝可能是更合适的选择。

  5. 代码可读性和维护性:有时候,选择深拷贝还是浅拷贝也可能受到代码可读性和维护性的影响。如果代码逻辑更清晰和易于理解,使用深拷贝可能更合适。

在这里插入图片描述

综上所述,选择深拷贝还是浅拷贝需要综合考虑对象的嵌套层次、数据的重要性和安全性、性能需求、资源消耗以及代码可读性和维护性等因素。在实际应用中,可以根据具体情况进行权衡和选择。

七、总结

总结在使用深拷贝和浅拷贝时需要注意的一些问题

在使用深拷贝和浅拷贝时,需要注意以下问题:

  1. 数据一致性:深拷贝会创建完全独立的副本,而浅拷贝只会复制第一层对象的属性。因此,如果修改浅拷贝对象的嵌套属性,原始对象也会受到影响,可能导致数据不一致的问题。在需要保持数据独立性和一致性的情况下,应使用深拷贝。

  2. 性能和内存消耗:深拷贝需要递归复制嵌套对象,可能会导致性能开销和内存消耗的增加。特别是在处理大型对象或嵌套层次较深的对象时,深拷贝可能会造成性能下降和内存占用过高的问题。在性能敏感的场景中,可以考虑使用浅拷贝。

  3. 引用类型的处理:对于引用类型(如数组、对象等),深拷贝和浅拷贝的行为可能会有所不同。深拷贝会创建引用类型的新副本,而浅拷贝只会复制引用,实际对象仍然共享。在处理引用类型时,需要特别注意拷贝的行为和后果。

  4. 循环引用问题:在对象之间存在循环引用的情况下,深拷贝可能会导致递归循环,引发栈溢出或无限循环的问题。为避免循环引用问题,可以使用一些特殊的方法来处理,如手动创建副本、使用哈希表记录已拷贝的对象等。

  5. 明确拷贝目的:在选择深拷贝或浅拷贝时,应明确拷贝的目的和需求。如果只需要复制对象的属性,不需要独立修改嵌套对象,可以使用浅拷贝。如果需要保持对象的独立性和数据安全性,应使用深拷贝。

在这里插入图片描述

总之,在使用深拷贝和浅拷贝时,需要根据具体情况考虑数据一致性、性能、内存消耗、引用类型处理、循环引用问题等因素,并明确拷贝的目的和需求,选择适合的拷贝方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1314998.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apple Find My「查找」认证芯片找哪家,认准伦茨科技ST17H6x芯片

深圳市伦茨科技有限公司(以下简称“伦茨科技”)发布ST17H6x Soc平台。成为继Nordic之后全球第二家取得Apple Find My「查找」认证的芯片厂家,该平台提供可通过Apple Find My认证的Apple查找(Find My)功能集成解决方案。…

STM32与Freertos入门(五)任务案例

1、实现功能 通过两个按键任务分别控制不同的点灯案例 创建 4 个任务:在点灯任务的基础上在创建两个按键任务: Task_led:间隔 500ms 闪烁 LE1; Task_led2:间隔 1000ms 闪烁 LED2; Task_key:如…

为了吃鸡苦练狙击,避免坑队友自己造一个狙击游戏!

引言 一文教会你造一个简易的狙击游戏。 说到狙击,相信大家都不陌生,无论是影视作品还是网络游戏,都经常能看到狙击枪的身影,最深刻的是它能够从百里之外,一枪爆头。 本文将介绍如何在Cocos Creator中造一个简易的狙…

Jenkins Pipeline 脚本优化实践:从繁琐到简洁

引言 在持续集成的过程中,Jenkins Pipeline 是非常关键的一环。它定义了如何自动编译、测试和部署代码。随着项目的不断发展,Pipeline 的复杂性也在不断上升,这就需要我们持续优化 Pipeline 脚本,以提高代码的可读性和维护性。本…

最好的猫粮排行榜前十名有哪些牌子?盘点好的主食冻干猫粮前五名牌子

现在很多猫咪因为吃了不好的猫粮,出现了各种问题,甚至有的还发生了悲剧,让猫主人心疼又无奈。要解决这个问题,选择一款健康又安全的主食冻干猫粮是非常关键的。优质的主食冻干猫粮不仅在配方上要健康,营养配比也要科学…

【深度学习】注意力机制(二)

本文介绍一些注意力机制的实现,包括EA/MHSA/SK/DA/EPSA。 【深度学习】注意力机制(一) 【深度学习】注意力机制(三) 目录 一、EA(External Attention) 二、Multi Head Self Attention 三、…

26 redis 中 replication/cluster 集群中的主从复制

前言 我们这里首先来看 redis 这边实现比较复杂的 replication集群模式 我们这里主要关注的是 redis 这边的主从同步的相关实现 这边相对比较简单, 我们直接基于 cluster集群模式 进行调试 主从命令同步复制 比如这里 master 是 redis_7002, slave 是 redis_7005 然后 这…

打开软木塞,我们来谈谈葡萄酒泡泡吧

香槟是任何庆祝场合的最佳搭配。从婚礼和生日到单身派对和典型的周五晚上,这款气泡饮料是生活中特别聚会的受欢迎伴侣。 来自云仓酒庄品牌雷盛红酒分享你知道吗,你喜欢喝的那瓶香槟酒可能根本不是香槟,而是汽酒?你不是唯一一个认…

6个超好用的小众图片素材网站,高清、免费,值得收藏~

推荐几个超好用的图片素材网站,免费下载,还可以商用,建议收藏哦~ 1、菜鸟图库 https://www.sucai999.com/pic.html?vNTYwNDUx 我推荐过很多次的设计素材网站,除了设计类素材,还有很多自媒体可以用到的高清图片、背景…

最好的猫粮排行榜前十名有哪些品牌?质量好的主食冻干猫粮分享

为什么越来越多人推荐冻干猫粮喂养呢?主食冻干猫粮究竟是最适应猫饮食习惯的喂养方式还是消费陷阱? 作为一个6年的宠物营养师,我以前接触过很多不同品种的猫咪,一只健康又漂亮的猫咪从表面上就能看出来!体型匀称刚好、…

大模型落地,向量数据库到底能做什么?

▼最近直播超级多,预约保你有收获 今晚直播:《AI编程向量数据库架构设计案例实践》 —1— 大模型的“数据局限性” 数据局限对企业做 LLM 大模型带来的影响,可归结为以下三点: 第一点:对数据的管理和运维。随着文本、…

LeetCode(63)旋转链表【链表】【中等】

目录 1.题目2.答案3.提交结果截图 链接: 旋转链表 1.题目 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 示例 1: 输入:head [1,2,3,4,5], k 2 输出:[4,5,1,2,3]示例 2&…

深入理解LightGBM

1. LightGBM简介 GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型,其主要思想是利用弱分类器(决策树)迭代训练以得到最优模型,该模型具有训练效果好、不易过拟合等优点。GBDT不仅在工业界应用广泛&#…

python初试二

连接数据库 Django为多种数据库后台提供了统一的调用API。根据需求不同,Django可以选择不同的数据库后台。MySQL算是最常用的数据库。我们这里将Django和MySQL连接。 在Linux终端下启动mysql: $mysql -u root -p 在MySQL中创立Django项目的数据库: …

【数据结构和算法】判断子序列

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一:双指针 三、代码 3.1 方法一:双指针 3.1.1 Java易懂版:…

Cosmopolitan Libc:让 C 语言一次构建、随处运行 | 开源日报 No.109

jart/cosmopolitan Stars: 12.9k License: ISC Cosmopolitan Libc 使 C 成为一种构建一次运行在任何地方的语言,就像 Java 一样,但它不需要解释器或虚拟机。相反,它重新配置了标准 GCC 和 Clang 以输出符合 POSIX 标准的多语言格式&#xff…

VS Code连接远程Linux服务器调试C程序

1.在 VS Code 上安装扩展 C/C 2.通过 VS Code 连接远程 Linux 服务器 3.通过 VS Code 在远程 Linux 服务器上安装扩展 C/C 4.打开远程 Linux 服务器上的文件夹 【注】本文以 /root/ 为例。 5.创建项目文件夹,并在项目文件夹下创建C程序 6.按 F5,选…

数据挖掘任务一般流程

数据挖掘是从大量数据中提取有价值信息的过程。它涉及多个步骤,每一步都对整个数据挖掘过程至关重要。以下是数据挖掘任务的一般流程: 业务理解: 确定业务目标。评估当前情况。定义数据挖掘问题。制定一个初步计划来达到这些目标。 数据理…

JVM的类的生命周期

目录 前言 1. 加载(Loading): 2. 验证(Verification): 3. 准备(Preparation): 4. 解析(Resolution): 5. 初始化(Ini…

解决ES伪慢查询

一、问题现象 服务现象 服务接口的TP99性能降低 ES现象 YGC:耗时极其不正常, 峰值200次,耗时7sFULL GC:不正常,次数为1但是频繁,STW 5s慢查询:存在慢查询5 二 解决过程 1、去除干扰因素 从现象上看应用是由于某种…