<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <p><img src="https://i-blog.csdnimg.cn/blog_migrate/556eb48030fa6d3dccddf9aff.png#pic_center" alt="在这里插入图片描述" /></p>
讯享网
深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在编程中常用的两种对象复制方式。
- 浅拷贝是创建一个新的对象,将原始对象的属性值复制到新对象中。如果属性是基本类型,则直接复制其值;如果属性是引用类型,则复制引用而不是实际对象。
- 浅拷贝只复制对象的一层,对于嵌套的对象或数组,仅复制它们的引用。因此,当原始对象的属性发生变化时,浅拷贝的对象也会受到影响。
- 在 JavaScript 中,可以使用 Object.assign() 或扩展运算符 … 来实现浅拷贝。
- 深拷贝是创建一个全新的对象,并递归地将原始对象及其所有嵌套的对象完全复制到新对象中。即使原始对象的属性发生变化,深拷贝的对象也不会受到影响。
- 深拷贝会遍历整个对象树,复制每个对象的值,并为其创建新的引用。这样可以确保每个对象都是独立的。
- 在 JavaScript 中,可以使用 JSON 序列化和反序列化方法 JSON.parse(JSON.stringify(obj)) 来实现深拷贝。但需要注意,该方法有一些限制,例如无法复制函数、循环引用等。
使用时需要根据具体的需求来选择使用浅拷贝还是深拷贝。如果只需要复制对象的一层属性,并且不关心原始对象的属性改变对复制后的对象是否产生影响,可以使用浅拷贝。如果需要确保复制后的对象与原始对象完全独立,并且不受原始对象的变化影响,应该使用深拷贝。
常见的深拷贝方式包括:
- :通过编写递归函数,遍历对象的所有属性,并创建新的对象进行复制。对于嵌套的对象或数组,递归调用复制函数。这种方法需要自己处理循环引用和特殊数据类型(如函数)的情况。
讯享网
- :使用 JSON.stringify() 方法将对象转换为字符串,再使用 JSON.parse() 方法将字符串转换回对象。这种方法简单易行,可以实现深拷贝,但无法复制特殊数据类型(如函数、正则表达式)和循环引用。
- :许多 JavaScript 的第三方库(如 lodash、jQuery)提供了深拷贝的实现。这些库通常有专门的函数(如 _.cloneDeep()),可以方便地进行深拷贝操作,并且处理了循环引用等特殊情况。
讯享网
- 对象或数组的修改:当需要对一个对象或数组进行修改,但又不想影响原始数据时,可以使用深拷贝创建一个副本进行修改。
- 数据传递和处理:当需要将对象或数组作为参数传递给函数,并且希望在函数内部修改数据时,使用深拷贝可以确保原始数据不会被改变。
- 缓存数据:当需要缓存某个对象或数组的状态,并在后续操作中恢复到缓存的状态时,可以使用深拷贝创建一个备份,以便随时恢复。
- 避免引用共享:当多个变量需要引用同一个对象或数组时,如果不希望它们共享引用关系,可以使用深拷贝创建它们的独立副本。
- 数据比较和检查:当需要比较两个对象或数组是否相等时,可以先使用深拷贝创建它们的副本,然后进行比较操作,以避免引用相等而不实际内容相等的情况。
常见的浅拷贝方式有以下几种:
- :通过将一个对象的引用赋给另一个变量,两个变量会引用同一个对象,因此它们共享同一份数据。
- :该方法可以将一个或多个源对象的属性复制到目标对象中,也是浅拷贝,即只拷贝对象的第一层属性。
讯享网
- :该运算符可以将一个对象或数组“展开”为多个参数,相当于使用 Object.assign() 方法进行拷贝。
- 简单的数据结构:当需要复制简单的数据结构,例如基本类型、普通对象或一维数组时,可以使用浅拷贝。
- 不需要修改原始数据:当不需要对原始对象或数组进行修改,并且只是希望获取一个副本用于读取或传递给其他函数时,可以使用浅拷贝。
- 大规模数据集合:当处理大规模的数据集合时,为了节省内存和提高性能,可以使用浅拷贝来创建一份数据的快照,以备后续操作使用。
- 对象或数组的扁平化:当需要将嵌套的对象或多维数组转换为一维结构时,可以使用浅拷贝来创建一个扁平化的副本。
- 实现对象合并:当需要将多个对象的属性合并到一个新对象中时,可以使用浅拷贝将多个对象合并成一个对象。
- 都是用于复制对象或数组的方法,可以创建原始数据的副本。
- 在特定情况下都可以用于避免原始数据被修改影响到副本的情况。
- 拷贝层级:深拷贝会递归复制对象或数组的所有属性或元素,包括嵌套的子对象或数组,而浅拷贝只复制第一层的属性或元素,不会递归复制嵌套结构。
- 引用关系:深拷贝创建的是新的独立对象或数组,与原始数据没有任何关联,而浅拷贝复制的是对象或数组的引用,副本与原始数据共享部分引用。
- 数据完整性:深拷贝保留原始数据的完整性,复制的是完整的数据结构,而浅拷贝无法保留原始数据的完整性,对于嵌套结构只复制引用。
- 对原始数据的影响:深拷贝创建的副本修改不会影响原始数据,而浅拷贝创建的副本修改可能会影响原始数据。
讯享网
在这个示例中,我们使用copy.copy()函数进行浅拷贝。结果表明,虽然我们修改了浅拷贝后的数据,但原始数据也发生了变化。这是因为浅拷贝只复制了原始列表的引用,而没有递归地复制嵌套列表。
在这个示例中,我们使用copy.deepcopy()函数进行深拷贝。结果表明,当我们修改深拷贝后的数据时,原始数据没有受到影响。这是因为深拷贝递归地复制了所有嵌套的列表,创建了原始数据的完整副本。
利:
- 复制对象的完整数据结构:深拷贝会递归复制对象或数组的属性或元素,包括嵌套的子对象或数组,可以复制对象的完整数据结构,保留原始数据的完整性。

- 独立副本:深拷贝会创建新的独立对象或数组,而不是共享引用,它们与原始数据没有任何关联,修改副本不会影响原始数据。
- 处理循环引用:深拷贝可以处理对象内部存在循环引用的情况,避免了无限递归或栈溢出等问题。
弊:
- 复制性能较低:由于深拷贝需要递归复制对象或数组的所有属性或元素,可能会消耗大量的时间和内存资源,对性能造成一定影响。
- 可能存在对象方法失效问题:在深拷贝过程中,如果对象或数组的属性或元素中包含函数或方法,那么这些函数或方法可能会在复制后失效,这可能会导致应用程序出现异常或错误。
利:
- 简单快速:浅拷贝是一种简单且高效的复制方式,操作简单快速。
- 节省内存:由于浅拷贝只复制第一层属性或元素,而不会递归复制嵌套的子对象或数组,因此可以节省内存空间。
- 保留原始引用关系:浅拷贝会保留原始对象或数组的引用关系,即拷贝后的对象或数组与原始对象或数组共享相同的引用,可以在一定程度上减少数据冗余。
弊:
- 共享引用关系:由于浅拷贝只复制引用,而不是创建新的独立对象或数组,所以当修改拷贝后的对象或数组时,原始对象或数组也会受到影响,这可能导致意外的副作用。
- 不保留原始数据完整性:浅拷贝只复制第一层属性或元素,对于嵌套的子对象或数组,只复制它们的引用,而不是创建新的独立对象或数组,因此无法保留原始数据的完整性。
- 无法处理循环引用:如果原始对象存在循环引用,即对象内部的属性或元素相互引用形成闭环,浅拷贝无法处理此类情况,可能会导致无限递归或栈溢出等问题。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/151676.html