JavaScript原生深拷贝API:structuredClone()一行代码替代传统方法

structuredClone()是什么
structuredClone() 是浏览器和 Node.js 的原生 API,底层使用更高效的 C++ 实现,比起 JS 层的 JSON.stringify(),JSON.parse() 组合,性能通常更好。
在结构复杂/嵌套多时差异更明显,不需要转成字符串再解析,避免了冗余的编码/解码过程。
structuredClone()环境支持
在 Node.js 17+、Chrome 98+、Firefox 94+ 中支持。
structuredClone()不会拷贝的内容
| 不支持或无法克隆的类型/结构 | 说明 |
|---|---|
函数 (Function) |
无法克隆函数或方法 |
| Symbol | Symbol 属性会被忽略 |
| 类实例的方法/原型链 | 原型链不会保留,克隆后不是原类的实例 |
| DOM 节点(如 Element、Node) | 不支持 DOM 对象(比如浏览器中的 HTML 元素) |
| Proxy 对象 | 无法克隆代理对象(Proxy) |
| WeakMap / WeakSet | 因其不可枚举和弱引用特性,无法被克隆 |
| 函数作用域内的闭包变量 | 本质上函数不能克隆,因此也无法保留闭包 |
| 不可序列化的 host 对象 | 如浏览器特有的某些对象(如 Window, FileList) |
基础案例
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: 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.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 (变成数组)
structuredClone()的兼容性判断
为了确保在所有目标浏览器中都能使用 structuredClone(),可以用如下代码安全使用 structuredClone(),在不支持的环境里自动回退到 JSON 方案(虽然功能会弱一些):
function deepClone(obj) {
if (typeof structuredClone === 'function') {
return structuredClone(obj);
} else {
// fallback: 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、V8 团队 blog 和真实项目测试):
- 深层嵌套对象(10 层以上):
structuredClone()明显更快; - 包含 Map、Set、Date、ArrayBuffer 的复杂对象:
structuredClone()能直接处理,而 JSON 克隆则需要额外转换或报错; - 平均测试中
structuredClone()比 JSON 快 1.5~5 倍,尤其在大型对象上提升更显著。
结语
目前,structuredClone() 已被所有主流浏览器支持。它为深拷贝问题提供了一个简单、高效的解决方案,所以大家可以拥抱这个 JavaScript 新特性。
以上关于JavaScript原生深拷贝API:structuredClone()一行代码替代传统方法的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » JavaScript原生深拷贝API:structuredClone()一行代码替代传统方法
微信
支付宝