当前位置:网站首页 > Vue.js开发 > 正文

js对象的深拷贝和浅拷贝(js 深拷贝对象)



在JavaScript编程中,拷贝对象是一个非常常见的需求。拷贝方式主要分为两种:浅拷贝深拷贝。本文将详细介绍这两种拷贝方式的概念、浏览器最新版本中的实现方法及其优劣、兼容性问题,以及常用的三方库实现。

浅拷贝仅复制对象的第一层属性。对于复杂(嵌套)对象,浅拷贝仅复制对象的引用,而不是实际内容。例如,Object.assign和数组的slice方法都是浅拷贝。

深拷贝则是复制对象的所有层级的属性,不管是基本类型还是复杂类型,目标对象都与源对象完全独立。这意味着修改目标对象不会影响源对象,反之亦然。

2.1.1 Object.assign

 
  

优点:

  • 语法简单,易于使用。

缺点:

  • 仅能实现浅拷贝,不适用于深层嵌套对象。

2.1.2 展开运算符 (...)

 
  

优点:

  • 与Object.assign类似,语法更加简洁。

缺点:

  • 同样仅能实现浅拷贝。

2.2.1 JSON 的 stringify 和 parse

 
  

优点:

  • 语法简单,适用于大多数场景,适用低版本浏览器。

缺点:

  • 只能深拷贝可以被 JSON 序列化的类型。不能处理函数、undefined、Symbol、Date、RegExp、Map、Set、Blob、File、ArrayBuffer等。对于包含循环引用的对象,会抛出错误。
  • 转换过程中会丢失类型信息,Date 会被转换为字符串,Map 和 Set 会被转换为普通对象和数组。
  • 由于需要先将对象转换为字符串,再解析回对象,性能相对较低,尤其是在对象较大或较复杂时。

2.2.2 structuredClone(obj, options)(最新浏览器特性)

基本使用

 
  

参数options

方法的第二个参数 是一个可选参数,用于自定义克隆过程。这个参数允许你指定如何处理某些特殊类型的对象。目前, 对象主要包含一个属性:

  1. : 这是一个数组,用于列出应该被转移而不是克隆的对象。

这里是 选项的主要用途:

  • 对于可转移对象(如 ArrayBuffer, MessagePort 等),你可以使用 选项来指示应该转移这些对象的所有权,而不是克隆它们。
  • 转移比克隆更高效,因为它只是将对象的所有权从一个上下文转移到另一个上下文,而不是创建一个完整的副本。
  • 转移后,原始对象在源上下文中将变为不可用。
 
  

需要注意的是, 方法和它的 参数仍然相对较新,未来可能会添加更多的选项。

优点:

  • 可以处理丰富的数据类型,包括对象、数组、日期、Map、Set、Blob、File、ArrayBuffer、TypedArray等,还能处理嵌套结构和循环引用。
  • 保留了对象的类型信息,例如,Date 仍然是 Date 对象,Map 仍然是 Map 对象,等等
  • 不能复制某些类型的对象,如函数、DOM 节点、WeakMap 和 WeakSet,它会抛出错误。
  • 通常在处理复杂对象时性能更好,因为它是原生实现的,优化了许多底层细节。

缺点:

  • 仅支持最新的浏览器。

上述方法无法对函数进行克隆,那么《如何克隆一个函数》呢?

这些方法均在现代浏览器中广泛支持,包括Chrome、Firefox、Safari等。

这两个方法在几乎所有现代与较旧版本的浏览器中均有良好的支持。

1723441880018.png 此方法为最新特性,支持情况如下:

  • Chrome: 98+
  • Firefox: 94+
  • Safari: 15.4+

由于这是新特性,旧版本浏览器可能不支持。

对于更加复杂的对象拷贝需求,可以考虑使用成熟的三方库,如Lodash、Underscore等。以下是两者的示例:

安装Lodash:

 
  

使用Lodash的:

 
  

安装Underscore:

 
  

使用Underscore的:

 
  

在JavaScript中,不同的拷贝方法有着不同的适用场景。浅拷贝适用于对象结构简单的场景,而深拷贝则适用于复杂嵌套对象。在现代浏览器环境下,是一个强大的新特性,能够处理各种复杂数据结构。在此之外,成熟的三方库如Lodash也提供了便捷的深拷贝功能。选择合适的方法取决于实际需求及目标浏览器的兼容性。

到此这篇js对象的深拷贝和浅拷贝(js 深拷贝对象)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • jshy是哪里烟草(jhyc是哪里的烟草公司)2025-09-06 20:36:04
  • ettercap 0.8.3(ettercap 0.8.3教程)2025-09-06 20:36:04
  • plsql注册码在哪里填(plsql14.0注册码)2025-09-06 20:36:04
  • jsj是哪个男明星(jsy是哪个明星)2025-09-06 20:36:04
  • 数组方法js(数组方法截取)2025-09-06 20:36:04
  • ettercap安装教程(ettercap 0.8.3.1教程)2025-09-06 20:36:04
  • vue 具名插槽(vue具名插槽使用)2025-09-06 20:36:04
  • vuecli3安装失败(vue-cli3.0安装)2025-09-06 20:36:04
  • map转json字符串 空没有字段(map转化为json字符串)2025-09-06 20:36:04
  • vue2关闭父页面(vue 页面关闭)2025-09-06 20:36:04
  • 全屏图片