超详细的 JavaScript 深拷贝实现

发布于 2023-05-12 09:00:07 字数 3029 浏览 58 评论 0

配图源自 Feepik

此前写过一篇文章:JavaScript 深浅拷贝,其实没那么难!,但里面的拷贝处理显然不够理想。

今天再来详细的讲讲...

一、JSON.stringify() 的缺陷

利用 JavaScript 内置的 JSON 处理函数,可以实现简易的深拷贝:

const obj = {
  // ...
}
JSON.parse(JSON.stringify(obj)) // 序列化与反序列化

这个方法,其实能适用于 90% 以上的应用场景。毕竟多数项目下,很少会去拷贝一个函数什么的。

但不得不说,这里面有“坑”,这些“坑”是 JSON.stringify() 方法本身实现逻辑产生的:

JSON.stringify(value[, replacer[, space]])

该方法有以下特点:

  • 布尔值、数值、字符串对应的包装对象,在序列化过程会自动转换成其原始值。
  • undefined任意函数Symbol 值,在序列化过程有两种不同的情况。若出现在非数组对象的属性值中,会被忽略;若出现在数组中,会转换成 null
  • 任意函数undefined 被单独转换时,会返回 undefined
  • 所有以 Symbol 为属性键的属性都会被完全忽略,即便在该方法第二个参数 replacer 中指定了该属性。
  • Date 日期调用了其内置的 toJSON() 方法转换成字符串,因此会被当初字符串处理。
  • NaNInfinity 的数值及 null 都会当做 null
  • 这些对象 MapSetWeakMapWeakSet 仅会序列化可枚举的属性。
  • 被转换值如果含有 toJSON() 方法,该方法定义什么值将被序列化。
  • 对包含 循环引用 的对象进行序列化,会抛出错误。

二、深拷贝的边界

其实,针对以上两个内置的全局方法,还有这么多情况不能处理,是不是很气人。其实不然,我猜测 JSON.parse()JSON.stringify() 只是让我们更方便地操作符合 JSON 格式的 JavaScript 对象或符合 JSON 格式的字符串。

至于上面提到的“坑”,很明显是不符合作为跨平台数据交换的格式要求的。在 JSON 中,它有 null,是没有 undefinedSymbol 类型、函数等。

JSON 是一种数据格式,也可以说是一种规范。JSON 是用于跨平台数据交流的,独立于语言和平台。而 JavaScript 对象是一个实例,存在于内存中。JavaScript 对象是没办法传输的,只有在被序列化为 JSON 字符串后才能传输。

此前写过一篇文章,介绍了 JSON 和 JavaScript 的关系以及上述两个方法的一些细节。可看:详谈 JSON 与 JavaScript

如果自己实现一个深拷贝的方法,其实是有很多边界问题要处理的,至于这些种种的边界 Case,要不要处理最好从实际情况出发。

常见的边界 Case 有什么呢?

主要有循环引用、包装对象、函数、原型链、不可枚举属性、Map/WeakMap、Set/WeakSet、RegExp、Symbol、Date、ArrayBuffer、原生 DOM/BOM 对象等。

**就目前而言,第三方最完善的深拷贝方法是 Lodash 库的 _.cloneDeep() 方法了。在实际项目中,如需处理 JSON.stringify() 无法解决的 Case,我会推荐使用它。**否则请使用内置 JSON 方法即可,没必要复杂化。

但如果为了学习深拷贝,那应该要每种情况都要去尝试实现一下,我想这也是你在看这篇文章的原意。这样,无论是实现特殊要求的深拷贝,还是面试,都可以从容应对。

下面一起来学习吧,如有不足,欢迎指出

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

送舟行

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

亽野灬性zι浪

文章 0 评论 0

少年亿悲伤

文章 0 评论 0

南七夏

文章 0 评论 0

qq_EJoXxu

文章 0 评论 0

17780639550

文章 0 评论 0

萌逼全场

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文