JavaScript typed arrays

这篇翻译不完整。请帮忙从英语翻译这篇文章

JavaScript类型数组是一种类似数组的对象,并提供用于访问原始二进制数据的机制。 正如你可能已经知道,Array 对象动态增长和缩减,可以有任何JavaScript值。JavaScript引擎执行优化,以便这些数组是快速的。然而,随着Web应用程序变得越来越强大,添加了诸如音频和视频操纵,使用WebSockets访问原始数据等功能,它已经变得清楚,有时,将有助于JavaScript代码能够快速和容易地处理类型数组中的原始二进制数据。

但是,类型数组不能与正常数组混淆,因为在类型数组上调用  Array.isArray()  会返回false。此外,并不是所有可用于正常数组的方法是能被类型数组支持的 (例如 push和 pop)。

冲区和视图:类型化数组架构

为了实现最大的灵活性和效率, JavaScript 类型数组(Typed Arrays)拆分成缓冲区和类型化数组视图. 一个缓冲区(由 ArrayBuffer 对象实现)代表一个数据块的对象 ;它没有格式可言, 并没有提供任何机制来访问其内容. 为了访问包含在缓冲区中的内存, ,需要使用视图. 视图提供了一个上下文 — 即数据类型、起始偏移量和元素数 — 将数据转换为实际类型的数组.

Typed arrays in an ArrayBuffer

数组缓冲

 ArrayBuffer 是一种数据类型 ,用于表示一个通用的、固定长度的二进制数据缓冲区. 你不能直接操纵一个ArrayBuffer内容; 相反,你能创建一个数组类型的视图或DataView代表特定格式的缓冲区,并使用读写缓冲区的内容.

类型化数组视图

类型化数组视图具有自描述性的名字和所有常用的数值类型像Int8Uint32Float64 等等. 有一种特殊类型的数组, Uint8ClampedArray. 它夹值在0和255之间. 例如对ImageData(Canvas 数据处理)有用的.

Type Size in bytes Description Web IDL type Equivalent C type
Int8Array 1 8-bit two's complement signed integer byte int8_t
Uint8Array 1 8-bit unsigned integer octet uint8_t
Uint8ClampedArray 1 8-bit unsigned integer (clamped) octet uint8_t
Int16Array 2 16-bit two's complement signed integer short int16_t
Uint16Array 2 16-bit unsigned integer unsigned short uint16_t
Int32Array 4 32-bit two's complement signed integer long int32_t
Uint32Array 4 32-bit unsigned integer unsigned long uint32_t
Float32Array 4 32-bit IEEE floating point number unrestricted float float
Float64Array 8 64-bit IEEE floating point number unrestricted double double

数据视图

The DataView is a low-level interface that provides a getter/setter API to read and write arbitrary data to the buffer. This is useful when dealing with different types of data, for example. Typed array views are in the native byte-order (see Endianness) of your platform. With a DataView you are able to control the byte-order. It is big-endian by default and can be set to little-endian in the getter/setter methods.

使用类型数组的Web API

FileReader.prototype.readAsArrayBuffer()
The FileReader.prototype.readAsArrayBuffer() method starts reading the contents of the specified Blob or File.
XMLHttpRequest.prototype.send()
XMLHttpRequest instances' send() method now supports typed arrays and ArrayBuffer objects as argument.
ImageData.data
Is a Uint8ClampedArray representing a one-dimensional array containing the data in the RGBA order, with integer values between 0 and 255 inclusive.

 

范例

使用带缓冲区的视图

First of all, we will need to create a buffer, here with a fixed length of 16-bytes:

var buffer = new ArrayBuffer(16);

At this point, we have a chunk of memory whose bytes are all pre-initialized to 0. There's not a lot we can do with it, though. We can confirm that it is indeed 16 bytes long, and that's about it:

if (buffer.byteLength === 16) {
  console.log("Yes, it's 16 bytes.");
} else {
  console.log("Oh no, it's the wrong size!");
}

Before we can really work with this buffer, we need to create a view. Let's create a view that treats the data in the buffer as an array of 32-bit signed integers:

var int32View = new Int32Array(buffer);

Now we can access the fields in the array just like a normal array:

for (var i = 0; i < int32View.length; i++) {
  int32View[i] = i * 2;
}

This fills out the 4 entries in the array (4 entries at 4 bytes each makes 16 total bytes) with the values 0, 2, 4, and 6.

同一数据的多个视图

Things start to get really interesting when you consider that you can create multiple views onto the same data. For example, given the code above, we can continue like this:

var int16View = new Int16Array(buffer);

for (var i = 0; i < int16View.length; i++) {
  console.log("Entry " + i + ": " + int16View[i]);
}

Here we create a 16-bit integer view that shares the same buffer as the existing 32-bit view and we output all the values in the buffer as 16-bit integers. Now we get the output 0, 0, 2, 0, 4, 0, 6, 0.

You can go a step farther, though. Consider this:

int16View[0] = 32;
console.log("Entry 0 in the 32-bit array is now " + int32View[0]);

The output from this is "Entry 0 in the 32-bit array is now 32". In other words, the two arrays are indeed simply views on the same data buffer, treating it as different formats. You can do this with any view types.

使用复杂的数据结构

By combining a single buffer with multiple views of different types, starting at different offsets into the buffer, you can interact with data objects containing multiple data types. This lets you, for example, interact with complex data structures from WebGL, data files, or C structures you need to use while using js-ctypes.

Consider this C structure:

struct someStruct {
  unsigned long id;
  char username[16];
  float amountDue;
};

You can access a buffer containing data in this format like this:

var buffer = new ArrayBuffer(24);

// ... read the data into the buffer ...

var idView = new Uint32Array(buffer, 0, 1);
var usernameView = new Uint8Array(buffer, 4, 16);
var amountDueView = new Float32Array(buffer, 20, 1);

Then you can access, for example, the amount due with amountDueView[0].

Note: The data structure alignment in a C structure is platform-dependent. Take precautions and considerations for these padding differences.

转换为正常数组

After processing a typed array, it is sometimes useful to convert it back to a normal array in order to benefit from the Array prototype. This can done using Array.from, or using the following code where Array.from is unsupported.

var typedArray = new Uint8Array([1, 2, 3, 4]),
    normalArray = Array.prototype.slice.call(typedArray);
normalArray.length === 4;
normalArray.constructor === Array;

规范

Specification Status Comment
Typed Array Specification Obsolete Superseded by ECMAScript 6.
ECMAScript 2015 (6th Edition, ECMA-262)
TypedArray Objects
Standard Initial definition in an ECMA standard.
ECMAScript 2017 Draft (ECMA-262)
TypedArray Objects
Draft  

浏览器兼容性

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 7.0 4.0 (2) 10 11.6 5.1
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 4.0 (Yes) 4.0 (2) 10 11.6 4.2

了解更多

 

 

文档标签和贡献者

标签: 
 最后编辑者: lvsiyuan,