我正在使用ArrayBuffer
对象,我想复制它们。虽然这对于实际指针和memcpy
来说相当容易,但我找不到任何直接的方法来在Javascript中执行它。
现在,这是我复制我的ArrayBuffers
的方式:
function copy(buffer)
{
var bytes = new Uint8Array(buffer);
var output = new ArrayBuffer(buffer.byteLength);
var outputBytes = new Uint8Array(output);
for (var i = 0; i < bytes.length; i++)
outputBytes[i] = bytes[i];
return output;
}
有更漂亮的方式吗?
ArrayBuffer
应该支持slice
(http://www.khronos.org/registry/typedarray/specs/latest/)所以你可以尝试,
buffer.slice(0);
它适用于Chrome 18但不适用于Firefox 10或11.至于Firefox,您需要手动复制它。您可以在Firefox中修补slice()
,因为Chrome slice()
的性能优于手动副本。这看起来像,
if (!ArrayBuffer.prototype.slice)
ArrayBuffer.prototype.slice = function (start, end) {
var that = new Uint8Array(this);
if (end == undefined) end = that.length;
var result = new ArrayBuffer(end - start);
var resultArray = new Uint8Array(result);
for (var i = 0; i < resultArray.length; i++)
resultArray[i] = that[i + start];
return result;
}
然后你可以打电话,
buffer.slice(0);
在Chrome和Firefox中复制阵列。
我更喜欢以下方法
function copy(src) {
var dst = new ArrayBuffer(src.byteLength);
new Uint8Array(dst).set(new Uint8Array(src));
return dst;
}
看来简单地传入源数据视图会执行一个副本:
var a = new Uint8Array([2,3,4,5]);
var b = new Uint8Array(a);
a[0] = 6;
console.log(a); // [6, 3, 4, 5]
console.log(b); // [2, 3, 4, 5]
在FF 33和Chrome 36中测试过。
嗯......如果它是你要切片的Uint8Array(逻辑上应该是这样),这可能有效。
if (!Uint8Array.prototype.slice && 'subarray' in Uint8Array.prototype)
Uint8Array.prototype.slice = Uint8Array.prototype.subarray;
chuckj答案更快,更复杂的版本。应该在大型阵列上使用约8倍的复制操作。基本上我们尽可能多地复制8字节块,然后复制剩余的0-7字节。这在当前版本的IE中特别有用,因为它没有为ArrayBuffer实现切片方法。
if (!ArrayBuffer.prototype.slice)
ArrayBuffer.prototype.slice = function (start, end) {
if (end == undefined) end = that.length;
var length = end - start;
var lengthDouble = Math.floor(length / Float64Array.BYTES_PER_ELEMENT);
// ArrayBuffer that will be returned
var result = new ArrayBuffer(length);
var that = new Float64Array(this, start, lengthDouble)
var resultArray = new Float64Array(result, 0, lengthDouble);
for (var i = 0; i < resultArray.length; i++)
resultArray[i] = that[i];
// copying over the remaining bytes
that = new Uint8Array(this, start + lengthDouble * Float64Array.BYTES_PER_ELEMENT)
resultArray = new Uint8Array(result, lengthDouble * Float64Array.BYTES_PER_ELEMENT);
for (var i = 0; i < resultArray.length; i++)
resultArray[i] = that[i];
return result;
}