所有的 TypedArrayBuffer 实例都是基于 ArrayBuffer 之上的视图。 也就是说,尽管 TypedArrayBuffer 对象提供操作数据的方法, 但实际存放数据的是他们的 ArrayBuffer。 可以为同一个 ArrayBuffer 实例创建多个视图。 但需要特别注意,当使用 transferList 转移一个 ArrayBuffer 时 会导致所有基于此的 TypedArrayBuffer 实例变得无法使用。

    1. const ab = new ArrayBuffer(10);
    2. const u1 = new Uint8Array(ab);
    3. const u2 = new Uint16Array(ab);
    4. console.log(u2.length); // 打印 5
    5. port.postMessage(u1, [u1.buffer]);
    6. console.log(u2.length); // 打印 0

    对于 Buffer 实例,确切地说,它的 ArrayBuffer 是否可以被转移还是克隆, 完全取决于该实例的创建方式,无法一概而论。

    ArrayBuffer 可以用 [markAsUntransferable()][] 来声明它总是应该被克隆并且从不会被转移。

    根据一个 Buffer 实例如何被创建,它可以拥有自己的 ArrayBuffer 或没有。 除非已知该 Buffer 实例拥有它否则 ArrayBuffer 无法被转移。 需要注意,对于从内部的 Buffer 内存池创建的实例 (例如使用 Buffer.from()Buffer.allocUnsafe()), 它们将总是被克隆而无法被转移,并且会克隆整个 Buffer 内存池发送。 这种行为可能会导致不可预料的高内存占用和安全问题。

    关于 Buffer 内存池的更多内容参考 [Buffer.allocUnsafe()][]。

    如果一个 Buffer 实例使用 Buffer.alloc()Buffer.allocUnsafeSlow() 创建, 那么它的 ArrayBuffer 总是可以被转移, 不过这么做会导致其它基于此 ArrayBuffer 的视图变得无法使用。