--- title: ArrayBuffer.transfer() slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/transfer translation_of: Archive/Web/JavaScript/ArrayBuffer.transfer ---
静态ArrayBuf
fer.transfer() 方法返回一个新的ArrayBuffer, 其内容取自oldBuffer的数据,并且根据 newByteLength 的大小来对数据进行截取或者以0扩展。 如果 newByteLength 未定义,则使用 oldBuffer 的byteLength。这个操作使得 oldBuffer 处于被移除的状态。
ArrayBuffer.transfer(oldBuffer [, newByteLength]);
oldBuffer
ArrayBuffer
对象的字节长度。一个新的ArrayBuffer对象。
ArrayBuffer.transfer()
方法允许你增长和移除 ArrayBuffer
对象。不需复制就能增长一个ArrayBuffer的功能,对于大的缓冲区来说,有速度优势 (类似realloc) 。当释放底层内存时,移除ArrayBuffer的功能给开发者提供了显式控制。这避免了必须丢弃所有引用和等待垃圾回收。
var buf1 = new ArrayBuffer(40); new Int32Array(buf1)[0] = 42; var buf2 = ArrayBuffer.transfer(buf1, 80); buf1.byteLength; // 0 but if you use the polyfill then the value is still 40 buf2.byteLength; // 80 new Int32Array(buf2)[0]; // 42 var buf3 = ArrayBuffer.transfer(buf2, 0); buf2.byteLength; // 0 but if you use the polyfill then the value is still 80 buf3.byteLength; // 0
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, length) { source = Object(source); var dest = new ArrayBuffer(length); 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; } }); } return dest; 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) } } }; }
Not part of any current specification draft document, but has been proposed for a future ECMA-262 edition.
{{Compat("javascript.builtins.ArrayBuffer.transfer")}}