structuredclone处理arraybuffer时默认拷贝,需显式传入transfer选项才能零拷贝转移;transfer后原buffer变为detached,bytelength为0,且仅支持arraybuffer实例,typedarray须提取.buffer传入。

structuredClone 在处理 ArrayBuffer 时默认采用数据拷贝(copy),而非转移(transfer);如需真正转移(即原 ArrayBuffer 不再可用、内存零拷贝),必须显式传入 transfer 选项。
transfer 选项是关键,ArrayBuffer 不会自动转移
即使目标对象只含一个 ArrayBuffer,structuredClone 也不会自动将其移出原上下文。必须手动指定该 buffer 的引用到 transfer 数组中,否则得到的是副本,原 buffer 仍可读写,且新旧 buffer 占用双份内存。
- ✅ 正确写法(触发转移):
const cloned = structuredClone(obj, { transfer: [obj.buffer] }); - ❌ 错误写法(仅拷贝):
const cloned = structuredClone(obj); // ArrayBuffer 被复制,非转移
transfer 后原 ArrayBuffer 变为「detached」状态
一旦 ArrayBuffer 被列入 transfer 列表并完成克隆,其 .byteLength 立即变为 0,所有关联的 TypedArray 或 DataView 将抛出 TypeError(如 "Cannot read property 'length' of detached ArrayBuffer")。
- 转移后应立即放弃对原 buffer 及其视图的访问
- 可在转移前用
ArrayBuffer.isView()检查是否有活跃视图,避免意外访问 - 常见场景:将大 buffer 从主线程传给 Worker 时,用 transfer 避免序列化开销和内存冗余
只能转移 ArrayBuffer,不能转移 TypedArray 或 DataView
transfer 选项只接受 ArrayBuffer 实例。若传入 Uint8Array、DataView 等,会报错 TypeError: Cannot transfer given object。
- 正确做法:提取底层 buffer ——
typedArray.buffer或dataView.buffer - 例如:
const arr = new Uint8Array([1,2,3]);<br> structuredClone({ data: arr }, { transfer: [arr.buffer] });
跨上下文转移需双方支持,且不可逆
transfer 机制依赖底层平台(如浏览器或 Node.js)的结构化克隆算法实现。目前主流环境均支持,但转移后无法“退回”或“共享”buffer —— 它完全归属新上下文。
- 在 Worker 中接收转移后的 buffer,可直接使用,无需额外解析
- 主线程中 transfer 出去后,不能再用
postMessage(..., [buffer])再次发送同一 buffer - Node.js v18.13+ 和现代浏览器(Chrome 98+, Firefox 97+, Safari 16.4+)已稳定支持
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











