我们的志愿者还没有将这篇文章翻译为 中文 (简体)。加入我们帮助完成翻译!
This is an experimental technology
Because this technology's specification has not stabilized, check the compatibility table for usage in various browsers. Also note that the syntax and behavior of an experimental technology is subject to change in future versions of browsers as the specification changes.
The static ArrayBuffer.transfer()
method returns a new ArrayBuffer
whose contents have been taken from the oldBuffer
's data and then is either truncated or zero-extended by newByteLength
. If newByteLength
is undefined
, the byteLength
of the oldBuffer
is used. This operation leaves oldBuffer
in a detached state.
Syntax
ArrayBuffer.transfer(oldBuffer [, newByteLength]);
Parameters
oldBuffer
- An
ArrayBuffer
object from which to transfer. - newByteLength
- The byte length of the new
ArrayBuffer
object.
Return value
A new ArrayBuffer
object.
Description
The ArrayBuffer.transfer()
method allows you to grow and detach ArrayBuffer
objects. The ability to grow an ArrayBuffer
without copying has the advantage of being much faster for large buffers (similar to realloc). The ability to detach an ArrayBuffer
gives the developer explicit control over when the underlying memory is released. This avoids having to drop all references and wait for garbage collection.
Examples
var buf1 = new ArrayBuffer(40); new Int32Array(buf1)[0] = 42; var buf2 = ArrayBuffer.transfer(buf1, 80); buf1.byteLength; // 0 buf2.byteLength; // 80 new Int32Array(buf2)[0]; // 42 var buf3 = ArrayBuffer.transfer(buf2, 0); buf2.byteLength; // 0 buf3.byteLength; // 0
Polyfill
You can partially work around this by inserting the following code at the beginning of your scripts, allowing use of much of the functionality of transfer() in implementations that do not natively support it. This is not the exact equivalent of this API, but this function transfers data from one ArrayBuffer to another ArrayBuffer.
if(!ArrayBuffer.transfer) { ArrayBuffer.transfer = function (source, dest) { source = Object(source); dest = Object(dest); if(!(source instanceof ArrayBuffer) || !(dest instanceof ArrayBuffer)) { throw new TypeError("Source and destination must be ArrayBuffer instances"); } if(dest.byteLength >= source.byteLength) { var nextOffset = 0; var leftBytes = source.byteLength; var wordSizes = [8, 4, 2, 1]; wordSizes.forEach(function (_wordSize_) { if (leftBytes >= _wordSize_) { var done = transferWith(_wordSize_, source, dest, nextOffset, leftBytes); nextOffset = done.nextOffset; leftBytes = done.leftBytes; } }); } function transferWith(wordSize, source, dest, nextOffset, leftBytes) { var ViewClass = Uint8Array; switch (wordSize) { case 8: ViewClass = Float64Array; break; case 4: ViewClass = Float32Array; break; case 2: ViewClass = Uint16Array; break; case 1: ViewClass = Uint8Array; break; default: ViewClass = Uint8Array; break; } var view_source = new ViewClass(source, nextOffset, Math.trunc(leftBytes / wordSize)); var view_dest = new ViewClass(dest, nextOffset, Math.trunc(leftBytes / wordSize)); for(var i=0; i<view_dest.length; i++) { view_dest[i] = view_source[i]; } return { nextOffset : view_source.byteOffset + view_source.byteLength, leftBytes : source.byteLength - (view_source.byteOffset + view_source.byteLength) } } }; }
Specifications
Not part of any current specification draft document, but has been proposed for a future ECMA-262 edition.
Browser compatibility
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | No support | Nightly build | No support | No support | No support |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | No support | No support | Nightly build | No support | No support | No support |