网站首页 > 技术文章 正文
深拷贝是JavaScript里一个常见而又棘手的问题,长久以来,我们不得不依赖各种自定义方法或第三方库来解决这一问题。大多数人都会使用JSON.parse(JSON.stringify(obj))这种方式,但它存在众多限制。好消息是,现代JavaScript为我们带来了原生的解决方案:structuredClone()方法。
深拷贝的传统解决方案及其问题
回顾一下,我们通常使用以下方法来实现深拷贝:
这些方法各有缺点:
- JSON方法的局限性: 无法处理函数/Symbol类型/undefined值/循环引用,无法正确处理Date、RegExp、Map、Set等特殊对象,会丢失原型链
- 自定义递归函数: 实现复杂,容易出错,通常需要额外处理各种特殊类型,性能不一定理想
- 第三方库: 增加项目依赖,增加打包体积
structuredClone:现代JavaScript的深拷贝解决方案
2022年,WHATWG HTML标准引入了structuredClone()方法,现在它已被所有主流浏览器和Node.js支持。这个方法提供了一种高效、标准化的方式来创建复杂JavaScript对象的深拷贝。
基本用法
使用structuredClone()非常简单:
就是这么简单!一行代码,无需任何额外的库或复杂的递归函数。
structuredClone的优势
- 内置于JavaScript引擎,无需外部依赖
- 处理循环引用,不会像JSON方法那样抛出错误
- 正确处理大多数JavaScript内置类型,包括: Date对象/RegExp对象/Map和Set/ArrayBuffer和TypedArrays/Blob对象/File对象/ImageData对象/嵌套的复杂对象结构
处理循环引用的示例
支持的数据类型详解
structuredClone()支持的类型远超JSON方法:
const original = {
// 原始类型
string: 'Hello',
number: 123,
boolean: true,
null: null,
undefined: undefined, // JSON会丢失,structuredClone保留
// 日期对象 (JSON会转为字符串,structuredClone保持为Date对象)
date: newDate('2023-06-15'),
// 正则表达式 (JSON会转为空对象,structuredClone保持为RegExp对象)
regex: /pattern/g,
// 集合类型
map: newMap([['key', 'value']]),
set: newSet([1, 2, 3]),
// 二进制数据
arrayBuffer: newUint8Array([1, 2, 3]).buffer,
typedArray: newUint8Array([1, 2, 3]),
// 嵌套数组和对象
array: [1, 2, { nested: true }],
object: { nested: { deep: true } }
};
const clone = structuredClone(original);
// 验证类型保持一致
console.log(clone.dateinstanceofDate); // true
console.log(clone.regexinstanceofRegExp); // true
console.log(clone.mapinstanceofMap); // true
console.log(clone.setinstanceofSet); // true
console.log(clone.arrayBufferinstanceofArrayBuffer); // true
console.log(clone.typedArrayinstanceofUint8Array); // true
structuredClone的局限性
虽然structuredClone()解决了大多数深拷贝问题,但它仍有一些限制:
- 不支持函数:与JSON方法一样,函数不会被克隆
- 不克隆原型链:克隆的对象会丢失原始对象的原型链
- 不支持DOM节点
- 不支持Error对象
structuredClone() 是JavaScript生态系统中的一个重要进步,它为常见的深拷贝问题提供了一个简单、高效且标准化的解决方案。虽然它有一些限制,但在大多数常见场景中,它都是深拷贝的最佳选择。目前,structuredClone() 已被所有主流浏览器支持。
猜你喜欢
- 2025-05-02 对象 (基础详解)(对象指的是)
- 2025-05-02 JavaScript的核心易错点知识梳理(js的重点)
- 2025-05-02 网络钓鱼攻击使用隐形Unicode Trick隐藏JavaScript
- 2025-05-02 本想搞清楚ESM和CJS模块的转换问题,没想到写完我的问题更多了
- 2025-05-02 19个基本的JavaScript面试问题及答案(都是实用技巧)免费送
- 2025-05-02 day11:前端面试题(js)(前端面试题汇总.pdf)
- 2025-05-02 前端面试:JavaScript 中有几种数据类型?
- 2025-05-02 前端开发基础-JavaScript(三)(前端开发的基础)
- 2025-05-02 小白教你JavaScript 第二讲(javascript教程 csdn)
- 2025-05-02 JS学习笔记:三、数据类型(js数据类型有)
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- js判断是否空对象 (63)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- phprequire_once (61)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)