JavaScript:深克隆与浅克隆完全指南

💡 原文英文,约1700词,阅读约需6分钟。
📝

内容提要

浅克隆是创建新对象并复制原对象属性的方法,常用Object.assign()、扩展运算符和数组方法(如slice和concat)。深克隆则创建新引用,常用JSON.stringify()和Lodash的_.cloneDeep方法。structuredClone()是原生API,适合深度复制复杂数据结构。

🔎

延伸解读

浅克隆的共享引用风险

浅克隆只复制对象的第一层属性,如果属性值是引用类型(如对象或数组),则克隆对象和原对象会共享同一个内存地址。这意味着修改克隆对象中的嵌套对象或数组,原对象也会同步变化。例如,使用扩展运算符克隆时,修改嵌套属性会影响原对象。因此,浅克隆适用于只有基本类型属性的对象,或不需要独立修改嵌套数据的场景。

JSON深克隆的局限性

使用JSON.parse(JSON.stringify(obj))实现深克隆简单直接,但存在明显限制:它会丢失函数、undefined、Symbol,并将Date转换为字符串、RegExp转换为空对象,同时无法处理Map、Set等类型。此外,如果对象存在循环引用,该方法会抛出错误。因此,它仅适用于纯数据对象(如从API获取的JSON数据),不适用于包含复杂类型或循环结构的对象。

structuredClone()的原生优势与限制

structuredClone()是浏览器原生API,能递归复制嵌套对象和数组,支持Date、RegExp、Map、Set、ArrayBuffer等多种类型,且性能通常优于手动实现。但它不支持函数和Symbol,遇到循环引用会抛出错误。对于需要克隆包含函数或循环引用的对象,仍需使用Lodash的_.cloneDeep或手动实现。

手动实现深克隆的关键点

手动实现深克隆时,需处理非对象类型直接返回、使用WeakMap记录已复制对象以避免循环引用、针对Date和RegExp等特殊类型创建新实例。此外,还需递归复制所有自有属性。手动实现虽然灵活,但容易遗漏边界情况,如Map、Set等。若无特殊需求,优先使用structuredClone()或Lodash等成熟方案。

❓

Q&A

什么是浅克隆,它是如何实现的?

浅克隆是创建新对象并复制原对象属性的方法,常用Object.assign()、扩展运算符和数组方法(如slice和concat)实现。

深克隆与浅克隆有什么区别?

深克隆创建新引用并复制所有嵌套对象,而浅克隆只复制对象的第一层属性,引用类型的属性仍指向原对象。

如何使用JSON.stringify()实现深克隆?

可以通过JSON.stringify()将对象序列化为JSON字符串,然后使用JSON.parse()将其反序列化为新对象,从而实现深克隆。

Lodash的_.cloneDeep方法有什么优势?

Lodash的_.cloneDeep方法支持多种数据类型的深复制,能够处理复杂对象,避免手动实现深克隆的复杂性。

structuredClone()函数的特点是什么?

structuredClone()是原生API,支持深度复制复杂数据结构,能够处理多种JavaScript数据类型,但不支持函数和循环引用。

手动实现深克隆时需要注意哪些问题?

手动实现深克隆时需处理边界情况,如循环引用、特殊对象类型(如Date、RegExp)等,使用WeakMap可以避免循环引用问题。

🏷️

标签

➡️

继续阅读