定型数组是另一种形式的ArrayBuffer 视图。虽然概念上与DataView 接近,但定型数组的区别
在于,它特定于一种ElementType 且遵循系统原生的字节序。相应地,定型数组提供了适用面更广的
API 和更高的性能。设计定型数组的目的就是提高与WebGL 等原生库交换二进制数据的效率。由于定
型数组的二进制表示对操作系统而言是一种容易使用的格式,JavaScript 引擎可以重度优化算术运算、
按位运算和其他对定型数组的常见操作,因此使用它们速度极快。
创建定型数组的方式包括读取已有的缓冲、使用自有缓冲、填充可迭代结构,以及填充基于任意类
型的定型数组。另外,通过.from()和.of()也可以创建定型数组:
// 创建一个12 字节的缓冲
const buf = new ArrayBuffer(12);
// 创建一个引用该缓冲的Int32Array
const ints = new Int32Array(buf);
// 这个定型数组知道自己的每个元素需要4 字节
// 因此长度为3
alert(ints.length); // 3
// 创建一个长度为6 的Int32Array
const ints2 = new Int32Array(6);
// 每个数值使用4 字节,因此ArrayBuffer 是24 字节
alert(ints2.length); // 6
// 类似DataView,定型数组也有一个指向关联缓冲的引用
alert(ints2.buffer.byteLength); // 24
// 创建一个包含[2, 4, 6, 8]的Int32Array
const ints3 = new Int32Array([2, 4, 6, 8]);
alert(ints3.length); // 4
alert(ints3.buffer.byteLength); // 16
alert(ints3[2]); // 6
// 通过复制ints3 的值创建一个Int16Array
const ints4 = new Int16Array(ints3);
// 这个新类型数组会分配自己的缓冲
// 对应索引的每个值会相应地转换为新格式
alert(ints4.length); // 4
alert(ints4.buffer.byteLength); // 8
alert(ints4[2]); // 6
// 基于普通数组来创建一个Int16Array
const ints5 = Int16Array.from([3, 5, 7, 9]);
alert(ints5.length); // 4
alert(ints5.buffer.byteLength); // 8
alert(ints5[2]); // 7
// 基于传入的参数创建一个Float32Array
const floats = Float32Array.of(3.14, 2.718, 1.618);
alert(floats.length); // 3
alert(floats.buffer.byteLength); // 12
alert(floats[2]); // 1.6180000305175781
定型数组的构造函数和实例都有一个BYTES_PER_ELEMENT 属性,返回该类型数组中每个元素的大小:
alert(Int16Array.BYTES_PER_ELEMENT); // 2
alert(Int32Array.BYTES_PER_ELEMENT); // 4
const ints = new Int32Array(1),
floats = new Float64Array(1);
alert(ints.BYTES_PER_ELEMENT); // 4
alert(floats.BYTES_PER_ELEMENT); // 8
如果定型数组没有用任何值初始化,则其关联的缓冲会以0 填充:
const ints = new Int32Array(4);
alert(ints[0]); // 0
alert(ints[1]); // 0
alert(ints[2]); // 0
alert(ints[3]); // 0
- 定型数组行为
从很多方面看,定型数组与普通数组都很相似。定型数组支持如下操作符、方法和属性:
[]
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
indexOf()
join()
keys()
lastIndexOf()
length
map()
reduce()
reduceRight()
reverse()
slice()
some()
sort()
toLocaleString()
toString()
values()
其中,返回新数组的方法也会返回包含同样元素类型(element type)的新定型数组:
const ints = new Int16Array([1, 2, 3]);
const doubleints = ints.map(x => 2*x);
alert(doubleints instanceof Int16Array); // true
定型数组有一个Symbol.iterator 符号属性,因此可以通过for…of 循环和扩展操作符来操作:
const ints = new Int16Array([1, 2, 3]);
for (const int of ints) {
alert(int);
}
// 1
// 2
// 3
alert(Math.max(…ints)); // 3