structuredclone() 是现代 javascript 深拷贝二进制数据的推荐方法,能正确复制 arraybuffer、typedarray 等,避免 json 序列化丢失或递归拷贝不安全问题;但不支持函数、undefined、symbol 等非结构化值,且不自动 transfer。

structuredClone() 是现代 JavaScript 中处理复杂对象深拷贝的推荐方式,尤其适合包含 ArrayBuffer、TypedArray(如 Uint8Array、Float32Array)等二进制数据的对象——它能正确复制底层内存,避免引用共享或序列化失败。
为什么不能用 JSON.stringify / JSON.parse?
JSON 无法表示 ArrayBuffer 和 TypedArray,调用 JSON.stringify() 会将其转为空对象 {} 或忽略,导致数据丢失。传统递归深拷贝也无法安全处理共享内存、转移状态(如已 transfer 的 buffer)或跨 realm 对象。
structuredClone() 的基本用法与限制
该方法原生支持 ArrayBuffer、所有 TypedArray、DataView、ImageBitmap、Map、Set、普通对象/数组等。但需注意:
- 不支持函数、
undefined、Symbol、Promise、RegExp、Error等非结构化值 - 不支持
WebAssembly.Module、AudioData等较新或实验性类型(具体以浏览器支持为准) - 在
Worker或Service Worker中可用;主线程中 Chrome 98+、Firefox 94+、Safari 15.4+ 支持 - 若源对象含不可克隆项(如函数),会直接抛出
DataCloneError
拷贝含 ArrayBuffer 和 TypedArray 的对象示例
假设你有一个带二进制数据的配置对象:
const original = {
id: 'frame-001',
pixels: new Uint8ClampedArray([255, 0, 128, 255]), // RGBA
metadata: new Float32Array([1.2, -3.7, 0.0]),
buffer: new ArrayBuffer(16)
};
直接使用:
const cloned = structuredClone(original);
此时:
– cloned.pixels.buffer !== original.pixels.buffer(内存独立)
– cloned.pixels[0] === original.pixels[0](值一致)
– 修改 cloned.pixels[0] = 0 不会影响 original
处理 transferable 对象(如 transfer 后的 ArrayBuffer)
structuredClone() **不会自动 transfer**,它始终执行「复制」而非「移动」。如果你需要零拷贝迁移(例如从主线程传大 buffer 到 Worker),仍应使用 postMessage(..., [arrayBuffer]) 的 transfer list 机制。
但你可以组合使用:先用 structuredClone() 安全复制一份用于本地处理,再用 transfer 发送原始 buffer 到其他上下文。
注意:已 transfer 的 ArrayBuffer 在原上下文中变为 .byteLength === 0,此时调用 structuredClone() 会成功返回一个空 buffer —— 这是预期行为,不是错误。











