structuredclone原生支持arraybuffer、所有typedarray、dataview、imagebitmap;克隆后内存独立,大体积数据可用transfer零拷贝迁移,但需手动传入buffer实例而非视图。

structuredClone 是处理二进制数据流(如 ArrayBuffer、TypedArray、DataView)最直接、最安全的原生深拷贝方法,它能完整保留底层内存结构,避免 JSON 序列化丢失或手动递归出错。
支持哪些二进制类型?
structuredClone 原生支持以下与二进制数据强相关的类型:
- ArrayBuffer(包括已 detached 的 buffer,但克隆时会报错)
- 所有 TypedArray:Uint8Array、Int32Array、Float64Array、Uint8ClampedArray 等
- DataView(只要其 buffer 可克隆)
- ImageBitmap(需浏览器支持)
这些类型在克隆后,新视图拥有独立的内存副本,修改 cloned[0] 不会影响 original。
基础克隆:零配置即可生效
对普通二进制对象,无需额外参数:
- 直接传入含 TypedArray 或 ArrayBuffer 的对象即可
- 克隆结果中,buffer 实例不同,但内容一致
- 原始对象和克隆体完全隔离,无共享引用风险
示例:
const original = { id: 'img-1', pixels: new Uint8ClampedArray([255, 0, 128, 255]), meta: new Float32Array([1.1, -2.3]) };const cloned = structuredClone(original);
// cloned.pixels.buffer !== original.pixels.buffer
// cloned.pixels[0] === 255,且修改它不影响 original
大体积数据优化:用 transfer 避免复制开销
当 ArrayBuffer 较大(如几 MB 以上),可使用 transfer 选项移交所有权,实现零拷贝迁移:
- transfer 数组必须填入实际的 ArrayBuffer 实例,不能填 TypedArray
- transfer 后,原 buffer 立即 detached,byteLength 变为 0
- 克隆体中对应视图自动绑定新接管的内存
示例:
const buf = new ArrayBuffer(8 * 1024 * 1024); // 8MBconst view = new Uint8Array(buf);
const cloned = structuredClone(view, { transfer: [buf] });
console.log(buf.byteLength); // 0(已分离)
console.log(cloned.buffer.byteLength); // 8388608
常见陷阱与绕过方式
不是所有“看起来像二进制”的东西都能被 structuredClone 处理:
- WebAssembly.Module:不支持,会抛 DataCloneError;应保存 wasm 字节码(Uint8Array),后续重新 new WebAssembly.Module(bytes)
- 已 transfer 的 ArrayBuffer:若原 buffer 已被转移过,再传入 structuredClone 会失败;确保只 transfer 一次且在克隆前未被使用
- 嵌套 buffer 未显式声明 transfer:options.transfer 不会自动识别对象内部的 buffer,必须手动提取并传入
例如:data = { img: new Uint8Array(buf) } → transfer 要写 [buf],不能写 [data.img]











