在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
方法的第二个参数 是一个可选参数,用于自定义克隆过程。这个参数允许你指定如何处理某些特殊类型的对象。目前, 对象主要包含一个属性:
- : 这是一个数组,用于列出应该被转移而不是克隆的对象。
这里是 选项的主要用途:
- 对于可转移对象(如 ArrayBuffer, MessagePort 等),你可以使用 选项来指示应该转移这些对象的所有权,而不是克隆它们。
- 转移比克隆更高效,因为它只是将对象的所有权从一个上下文转移到另一个上下文,而不是创建一个完整的副本。
- 转移后,原始对象在源上下文中将变为不可用。
需要注意的是, 方法和它的 参数仍然相对较新,未来可能会添加更多的选项。
优点:
- 可以处理丰富的数据类型,包括对象、数组、日期、Map、Set、Blob、File、ArrayBuffer、TypedArray等,还能处理嵌套结构和循环引用。
- 保留了对象的类型信息,例如,Date 仍然是 Date 对象,Map 仍然是 Map 对象,等等
- 不能复制某些类型的对象,如函数、DOM 节点、WeakMap 和 WeakSet,它会抛出错误。
- 通常在处理复杂对象时性能更好,因为它是原生实现的,优化了许多底层细节。
缺点:
- 仅支持最新的浏览器。
上述方法无法对函数进行克隆,那么《如何克隆一个函数》呢?
这些方法均在现代浏览器中广泛支持,包括Chrome、Firefox、Safari等。
这两个方法在几乎所有现代与较旧版本的浏览器中均有良好的支持。
此方法为最新特性,支持情况如下:
- Chrome: 98+
- Firefox: 94+
- Safari: 15.4+
由于这是新特性,旧版本浏览器可能不支持。
对于更加复杂的对象拷贝需求,可以考虑使用成熟的三方库,如Lodash、Underscore等。以下是两者的示例:
安装Lodash:
使用Lodash的:
安装Underscore:
使用Underscore的:
在JavaScript中,不同的拷贝方法有着不同的适用场景。浅拷贝适用于对象结构简单的场景,而深拷贝则适用于复杂嵌套对象。在现代浏览器环境下,是一个强大的新特性,能够处理各种复杂数据结构。在此之外,成熟的三方库如Lodash也提供了便捷的深拷贝功能。选择合适的方法取决于实际需求及目标浏览器的兼容性。
到此这篇js对象的深拷贝和浅拷贝(js 深拷贝对象)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/26897.html