I want to detach arbitrarily ArrayBuffer.
In d8(v8), i can detach ArrayBuffer using %ArrayBufferNeuter(array.buffer);.
But, i don't know how to do it without debugging option like above.
Is there some generic method to detach ArrayBuffer?
4 Answers 4
To detach an ArrayBuffer you can use ArrayBuffer.prototype.transfer()
The transfer() method of ArrayBuffer instances creates a new ArrayBuffer with the same byte content as this buffer, then detaches this buffer.
const buffer = new ArrayBuffer(8);
console.log(buffer.detached); // false
const newBuffer = buffer.transfer();
console.log(buffer.detached); // true
console.log(newBuffer.detached); // false
Old answer / Alternative for browsers that do not support .transfer()
You can now detach an ArrayBuffer by using structuredClone with transferables argument.
An array of transferable objects in value that will be moved rather than cloned to the returned object.
// this detaches the buffer
structuredClone(arrayBuffer, { transfer: [arrayBuffer] });
function moveBuffer(arrayBuffer) {
return structuredClone(arrayBuffer, { transfer: [arrayBuffer] });
}
const buffer = new Uint8Array([1]).buffer;
const moved = moveBuffer(buffer);
console.log(buffer.byteLength === 0); // detached
console.log(moved.byteLength === 1);
moveBuffer though. If its purpose was to only detach the buffer, it shouldn't return a new one.Not yet, but there is a proposal to introduce such a method.
transfer() got spun out into a new proposal which is alive and kicking in stage 3 currently.function detachBuffer(buffer) {
try {
postMessage('', '', [buffer]);
} catch { }
}
new MessageChannel().port1.postMessage("", [buffer])Many of the solutions here have the problem of creating a new backed ArrayBuffer. However, you can use structuredClone in an unusual way to accomplish this:
function detachBuffer(arrayBuffer) {
structuredClone(null, { transfer: [arrayBuffer] });
}
The docs for transferable objects notes:
For both postMessage() and structuredClone(), transferred resources have to be attached to the data object, otherwise they would not be available on the receiving end, because the transferable array only indicates how certain resources should be sent, but does not actually send them (although they would always be detached).
In our case, this is exactly what we want - the resource being detached without being cloned. This is also why the .transfer() method is not helpful in this case.
ArrayBufferfrom main thread to worker thread is one way to detachmain thread's ArrayBuffer. Does it right?