JavaScript中structuredClone()新特性:一行代码实现高效深拷贝
目录
JavaScript新特性structuredClone():一行代码优化深拷贝策略
一、structuredClone()相关介绍
1、structuredClone()的定义
structuredClone()是浏览器与Node.js原生提供的API,其底层运用更高效的C++实现方式,相较于JS层面的JSON.stringify/parse组合,性能往往更为出色。当面对结构复杂或嵌套层级较多的情况时,差异会更加明显,它无需先转换成字符串再进行解析,避免了冗余的编码与解码过程。
2、structuredClone()的环境支持情况
该API在Node.js 17及以上版本、Chrome 98及以上版本、Firefox 94及以上版本中能够得到支持。
3、structuredClone()无法克隆的内容
下面列出了不支持或无法克隆的类型及结构情况:
不支持或无法克隆的类型/结构 | 具体说明 |
---|---|
函数(Function ) |
函数或者方法无法被克隆 |
Symbol | Symbol 属性会被忽略 |
类实例的方法/原型链 | 原型链不会被保留,克隆后的对象并非原类的实例 |
DOM节点(如Element、Node) | 不支持DOM对象,例如浏览器中的HTML元素 |
Proxy对象 | 代理对象(Proxy )无法被克隆 |
WeakMap / WeakSet | 由于其不可枚举以及弱引用的特性,无法被克隆 |
函数作用域内的闭包变量 | 本质上函数无法被克隆,所以闭包变量也无法保留 |
不可序列化的host对象 | 比如浏览器特有的某些对象,像Window , FileList 等 |
4、基础应用案例
structuredClone()能够支持Map、Set、Blob、Date、File等JSON.parse(JSON.stringify(obj))不支持的类型,示例如下:
const original = {
// 原始类型
string: 'Hello',
number: 123,
boolean: true,
null: null,
undefined: undefined, // JSON会丢失,structuredClone保留
// 日期对象(JSON会转为字符串,structuredClone保持为Date对象)
date: new Date('2023-06-15'),
// 正则表达式(JSON会转为空对象,structuredClone保持为RegExp对象)
regex: /pattern/g,
// 集合类型
map: new Map([['key', 'value']]),
set: new Set([1, 2, 3]),
// 二进制数据
arrayBuffer: new Uint8Array([1, 2, 3]).buffer,
typedArray: new Uint8Array([1, 2, 3]),
// 嵌套数组和对象
array: [1, 2, { nested: true }],
object: { nested: { deep: true } }
};
const clone = structuredClone(original);
// 验证类型保持一致
console.log(clone.date instanceof Date); // true
console.log(clone.regex instanceof RegExp); // true
console.log(clone.map instanceof Map); // true
console.log(clone.set instanceof Set); // true
console.log(clone.arrayBuffer instanceof ArrayBuffer); // true
console.log(clone.typedArray instanceof Uint8Array); // true
const clone2 = JSON.parse(JSON.stringify(original));
console.log(clone2.date instanceof Date); // false(变成字符串)
console.log(clone2.set instanceof Set); // false(变成数组)
5、structuredClone()的兼容性判断
可以使用以下代码来安全地使用structuredClone(),在不支持的环境中自动退回到JSON方案(尽管功能会有所欠缺):
function deepClone(obj) {
if (typeof structuredClone === 'function') {
return structuredClone(obj);
} else {
// 备用方案:JSON克隆(注意功能有限)
return JSON.parse(JSON.stringify(obj));
}
}
二、structuredClone()与JSON.parse(JSON.stringify(obj))的区别
1、对比表格
特性 | JSON.parse(JSON.stringify(obj)) | structuredClone(obj) |
---|---|---|
深拷贝 | 是 | 是 |
性能 | 较慢(需要先序列化再解析) | 更快(原生实现) |
支持循环引用 | 报错 | 支持 |
支持类型丰富度 | 仅支持普通对象、数组、字符串、数字、布尔、null | 支持更多类型(Map、Set、Blob、Date、File等) |
丢失信息 | 会丢失函数、undefined、Symbol、日期、原型链等 | 保留更多原始结构 |
错误处理 | 容易出错(如循环引用会直接报错) | 更安全,报错更明确 |
2、循环引用情况
循环引用指的是对象内部相互引用,形成“闭环”的结构,例如:
const obj = {};
obj.self = obj;
const cloned = structuredClone(obj);
如果使用JSON.stringify(obj)就会报错:TypeError: Converting circular structure to JSON。但structuredClone()能够正确处理这种情况。
三、structuredClone()在性能上的提升
依据多个社区的实测benchmark(比如JSBench.me、V8团队博客以及真实项目测试):
- 对于深层嵌套对象(10层以上),structuredClone()明显更快;
- 对于包含Map、Set、Date、ArrayBuffer的复杂对象,structuredClone()能够直接处理,而JSON克隆则需要额外转换或者报错;
- 平均测试中,structuredClone()比JSON快1.5到5倍,尤其在大型对象上提升更为显著。
四、结语
目前,structuredClone()已经被所有主流浏览器所支持。它为深拷贝问题提供了一个简便、高效的解决方案,赶快拥抱这个JavaScript新特性吧。
只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
版权声明:程序员胖胖胖虎阿 发表于 2025年7月22日 上午12:35。
转载请注明:JavaScript中structuredClone()新特性:一行代码达成高效深拷贝 | 胖虎的工具箱-编程导航
转载请注明:JavaScript中structuredClone()新特性:一行代码达成高效深拷贝 | 胖虎的工具箱-编程导航
相关文章
暂无评论...