structuredclone 是现代 javascript 中最可靠、最便捷的深拷贝方案,支持嵌套对象、数组、map、set、date、regexp、error、arraybuffer 及其视图、循环引用等,但排除函数、undefined、symbol、weakmap、weakset 和 dom 节点。

structuredClone 是现代 JavaScript 中最可靠、最便捷的深拷贝方案,尤其适合处理包含函数以外的复杂数据结构,比如嵌套对象、数组、Map、Set、Date、RegExp、ArrayBuffer 及其视图(如 Uint8Array)、Error 实例,甚至带循环引用的对象。
哪些数据能被 structuredClone 正确复制
它支持标准可序列化类型,但明确排除函数、undefined、Symbol、WeakMap、WeakSet 和 DOM 节点。只要数据不包含这些“不可克隆项”,就能安全使用:
- 普通对象与深层嵌套对象(含 null、布尔、数字、字符串)
- 数组(包括稀疏数组)和 TypedArray(如 Float32Array)
- Map 和 Set(键值对或元素都会被递归克隆)
- Date、RegExp、Error(会保留原型与属性,如 message、stack)
- ArrayBuffer 及其 DataView、TypedArray 视图(内存内容被完整复制)
- 带有循环引用的对象(自动识别并重建引用关系)
如何正确使用 structuredClone
调用方式极简,直接传入源值即可。注意它同步执行,不支持异步或自定义行为:
- 基本用法:
const copy = structuredClone(original); - 若需兼容旧环境,可用
try...catch回退到 JSON.parse(JSON.stringify(...))(仅限纯数据)或第三方库(如 lodash.cloneDeep) - 在 Worker 或跨 Realm 场景中依然有效,比手动实现更健壮
- 不能用于克隆 class 实例(除非其所有字段都可序列化且无方法),建议改用实例的 toPlainObject() + structuredClone
常见陷阱与规避建议
看似简单,但几个边界情况容易引发静默失败或意外行为:
- 遇到函数、Symbol 或 undefined 时直接抛出 DataCloneError,务必用 try 包裹并提供降级逻辑
- DOM 元素、window、document 等宿主对象无法克隆,尝试时会立即报错
- 克隆后对象与原对象完全隔离:修改 copy 不影响 original,反之亦然;但 ArrayBuffer 视图共享底层缓冲区?不——structuredClone 会复制缓冲区内容,视图彼此独立
- 性能上,对超大对象(如百 MB 级 ArrayBuffer)可能阻塞主线程,高频场景建议节流或移至 Worker
替代方案对比参考
当 structuredClone 不适用时,可按需选择:
- JSON 方法:快但只支持可 JSON 序列化的子集(丢 Date、RegExp、undefined、循环引用)
- lodash.cloneDeep:功能全、兼容好,但体积大,且对某些特殊对象(如自定义类)行为依赖其内部实现
- 手动递归实现:可控性强,但易漏边缘 case(如循环引用、不可枚举属性、原型链),维护成本高
- structuredClone + 自定义预处理:先剥离函数/Symbol,再克隆,最后还原(适合特定业务模型)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











