structuredclone() 不支持通过第二个参数直接实现所有权转移,而是通过 options.transfer 数组显式声明要移交的 arraybuffer 等可转移对象实例;transfer 中必须是实际引用的底层可转移对象,转移后原 arraybuffer 立即 detached。

structuredClone() 的第二个参数 不支持所有权转移,也无法用于控制特定原始缓冲区(如 ArrayBuffer)的所有权转移。
这是关键事实:structuredClone() 没有第二个参数能实现所有权转移。
截至 2024 年,该方法的规范签名是:
structuredClone(value, options?)
其中 options 是一个可选对象,唯一合法字段是 transfer(数组),用于指定 可转移对象(如 ArrayBuffer、MessagePort、ImageBitmap 等)的所有权移交——但这不是“第二个参数实现转移”,而是 options.transfer 数组声明哪些对象应被转移。
✅ 正确用法是:
const buf = new ArrayBuffer(1024);
const view = new Uint8Array(buf);
// 克隆并移交 buf 的所有权 → 原 buf 变为 detached
const cloned = structuredClone(view, { transfer: [buf] });
console.log(buf.byteLength); // 报错或返回 0(已 detached)
console.log(cloned.buffer.byteLength); // 1024,新 ArrayBuffer 已接管内存
⚠️ 注意:
-
transfer数组中必须是源值中实际引用的底层可转移对象(通常是arrayBuffer,而不是视图如Uint8Array); - 转移后,原
ArrayBuffer立即 detached,所有基于它的视图(TypedArray,DataView)将失效; -
transfer中列出的对象必须在value的克隆图中可达,否则抛出DataCloneError; - 不支持对普通对象属性、嵌套缓冲区自动识别转移 —— 必须显式传入
ArrayBuffer实例本身。
? 实用建议:
-
若你持有
TypedArray,需先提取.buffer:const arr = new Float32Array([1, 2, 3]); structuredClone(arr, { transfer: [arr.buffer] }); -
多个缓冲区可一并转移:
const a = new ArrayBuffer(100); const b = new ArrayBuffer(200); const data = { a: new Uint8Array(a), b: new Int16Array(b) }; structuredClone(data, { transfer: [a, b] }); -
❌ 错误写法(不会转移,且可能报错):
structuredClone(view, { transfer: [view] }); // view 不是可转移对象 structuredClone(view, [view.buffer]); // 第二个参数不是 options 对象 → TypeError
所以,并非“用第二个参数实现转移”,而是:
通过 options.transfer 数组,显式声明要移交所有权的 ArrayBuffer(或其它可转移对象)实例。
这能避免深拷贝大内存块,提升性能,也用于跨线程(Worker)安全传递二进制数据。
不复杂但容易忽略的是:你必须传 ArrayBuffer 本身,而不是它的视图;且转移后原缓冲区不可再用。











