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

在这里插入图片描述

🤍 前端开发工程师(主业)、技术博主(副业)、已过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.hqwc.cn/news/278967.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于ssm培训学校教学管理平台论文

摘 要 社会的进步,教育行业发展迅速,人们对教育越来越重视,在当今网络普及的情况下,教学管理模式也开始逐渐网络化,学校开始网络教学管理模式。 本文研究的培训学校教学管理平台基于SSM框架,采用Java技术和…

【unity小技巧】unity最完美的CharacterController 3d角色控制器,实现移动、跳跃、下蹲、奔跑、上下坡,复制粘贴即可

最终效果 文章目录 最终效果前言为什么使用CharacterControllerSimpleMove和Move如何选择?1. SimpleMove2. Move 配置CharacterController参数控制相机移动跳跃下蹲处理下坡抖动问题实现奔跑和不同移速控制完整代码完结 前言 其实一开始我是不打算写的,…

MyBatis执行Sql的流程分析

本文介绍MyBatis执行Sql的流程,关于在执行过程中缓存、动态SQl生成等细节不在本章中体现 还是以之前的查询作为列子: public class MyApp {public static void main(String[] args) {String resource "mybatis-config.xml";Reader reader;t…

【Spring Boot】快速入门

一、引言 1、什么是spring boot? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式&#xff…

如何在Centos 7环境下安装MySQL并登录

目录 先获取MySQL官方yum源 然后正常使用yum命令下载mysql即可完成MySQL的下载 使用mysql客户端登录mysqld服务端 能够登录mysql客户端后,我们最后还需要做一点配置 先获取MySQL官方yum源(包括对yum源的介绍) 介绍一下yum源 yum源就是一…

超燃超欢乐!修仙喜剧动画《师兄啊师兄》第二季稳健开播

12月14日,备受瞩目的《师兄啊师兄》第二季终于稳健开播!首播两集连放,同时第一季全13集限免,不仅便于新观众丝滑入坑,老观众也可以二刷重温,可以说是非常良心了! 《师兄啊师兄》改编自人气网络小…

指针(笔记2)

一、const修饰指针 变量是可以修改的,如果把变量的地址交给一个指针变量,通过指针变量也可以修改这个变量。 我们希望给一个变量加上一些限制,不能被修改,那么这就由const起作用。 1.const修饰变量 (1)const如果放在&#xff…

基于Qt的登录页面设计

题目: 完善对话框,点击登录对话框,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到其他界面 如果账号和…

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

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

K8s可视化kuboard 部署

创建资产 [rootkube-master ~]# kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml 查看对应资源 [rootkube-master ~]# kubectl get pod -n kuboard NAME READY STATUS RESTARTS AGE kuboard-agent-2-5c4f886…

基于JSP+Servlet+Mysql的建设工程监管信息

基于JSPServletMysql的建设工程监管信息 一、系统介绍二、功能展示1.企业信息列表2.录入项目信息3.项目信息列表 四、其它1.其他系统实现五.获取源码 一、系统介绍 项目名称:基于JSPServlet的建设工程监管信息 项目架构:B/S架构 开发语言:…

论文阅读——GroupViT

GroupViT: Semantic Segmentation Emerges from Text Supervision 一、思想 把Transformer层分为多个组阶段grouping stages,每个stage通过自注意力机制学习一组tokens,然后使用学习到的组tokens通过分组模块Grouping Block融合相似的图片tokens。通过这…