TypedArray
一个TypedArray对象描述了底层二进制数据缓冲区的类数组视图。没有称为TypedArray的全局属性,也没有直接可用的TypedArray构造函数。但是,有很多不同的全局属性,其值是指定元素类型的类型化数组构造函数,如下所列。在接下来的页面,你将找到可以与包含任意类型元素的任意类型化数组一起使用的常见属性和方法。
描述
TypedArray构造函数(通常归类为%TypedArray%,表示它的“内在性”,因为它与任何 JavaScript 程序暴露出的全局对象不对应)是所有TypedArray子类的通用父类。将%TypedArray%作为一个“抽象类”,其为所有类型化数组的子类提供了实用方法的通用接口。该构造函数没有直接暴露:没有全局的TypedArray属性。它只能通过Object.getPrototypeOf(Int8Array)及类似方式访问。
当创建TypedArray子类(例如Int8Array)的实例时,在内存的中会创建数组缓冲区,或者,如果将ArrayBuffer对象作为构造参数,则使用该ArrayBuffer。缓冲区地址被保存为实例的内部属性并且所有的%TypedArray%.prototype方法都将基于数组缓冲区地址设置和获取值。
TypedArray 对象
| 类型 | 值范围 | 字节大小 | 描述 | Web IDL 类型 | 等价的 C 类型 |
|---|---|---|---|---|---|
Int8Array | -128 到 127 | 1 | 8 位有符号整型(补码) | byte | int8_t |
Uint8Array | 0 到 255 | 1 | 8 位无符号整型 | octet | uint8_t |
Uint8ClampedArray | 0 到 255 | 1 | 8 位无符号整型(一定在 0 到 255 之间) | octet | uint8_t |
Int16Array | -32768 到 32767 | 2 | 16 位有符号整型(补码) | short | int16_t |
Uint16Array | 0 到 65535 | 2 | 16 位无符号整型 | unsigned short | uint16_t |
Int32Array | -2147483648 到 2147483647 | 4 | 32 位有符号整型(补码) | long | int32_t |
Uint32Array | 0 到 4294967295 | 4 | 32 位无符号整型 | unsigned long | uint32_t |
Float32Array | -3.4E38到3.4E38并且1.2E-38是最小的正数 | 4 | 32 位 IEEE 浮点数(7 位有效数字,例如1.234567) | unrestricted float | float |
Float64Array | -1.8E308到1.8E308并且5E-324是最小的正数 | 8 | 64 位 IEEE 浮点数(16 位有效数字,例如1.23456789012345) | unrestricted double | double |
BigInt64Array | -263到 263- 1 | 8 | 64 位有符号整型(补码) | bigint | int64_t(signed long long) |
BigUint64Array | 0 到 264- 1 | 8 | 64 位无符号整型 | bigint | uint64_t(unsigned long long) |
构造函数
该对象不能被直接实例化——试图去使用new构造它将会抛出TypeError。
new (Object.getPrototypeOf(Int8Array))(); // TypeError: Abstract class TypedArray not directly constructable
但是,你可以使用一个指定的类型化数组创建实例,例如Int8Array或BigInt64Array。这些对象的构造函数是通用的:
new TypedArray() new TypedArray(length) new TypedArray(typedArray) new TypedArray(object) new TypedArray(buffer) new TypedArray(buffer, byteOffset) new TypedArray(buffer, byteOffset, length)
其中,TypedArray是一个具体的构造函数。
备注:所有TypedArray子类的构造函数只能使用new构造。试图在没有new的情况下调用,会抛出TypeError。
参数
typedArray当使用
TypedArray子类的实例调用时,typedArray会被拷贝到一个新的类型数组中。对于非 bigintTypeedArray构造函数,typedArray参数仅可以是非 bigint 类型(例如Int32Array)。同样,对于 bigintTypedArray构造函数(BigInt64Array或BigUint64Array),typedArray参数仅可以是 bigint 类型。typedArray中的每个值在拷贝到新数组之前都转换为构造函数的相应类型。新的类型化数组的长度与typedArray参数的长度相同。object当使用的不是
TypedArray实例的对象调用时,将以与TypedArray.from()方法相同的方式创建一个新的类型化数组。length可选当使用非对象调用时,该参数将被视为指定类型化数组长度的数字。在内存中创建一个内部数组缓冲区,大小长度乘以
BYTES_PER_ELEMENT字节,用 0 填充。省略所有参数,等同于使用0作为参数。buffer、byteOffset可选、length可选当使用
ArrayBuffer或SharedArrayBuffer实例以及可选的byteOffset和length参数调用时,将创建一个新的指定缓冲区的类型化数组视图。byteOffset和length参数指定类型化数组视图将暴露的内存范围。如果忽略这两个参数,则是整个视图的所有buffer;如果仅忽略length,则是从byteOffset开始的buffer剩余部分的视图。
异常
所有TypeArray子类构造函数都以相同的方式运行。它们都会抛出以下异常:
TypeError抛出以下情况之一:
- 传递
typedArray,但它是 bigint 类型,而当前构造函数不是,反之亦然。 - 传递
typedArray,但它的缓冲区被分离了,或者直接传递分离了视图的buffer。
- 传递
RangeError抛出以下情况之一:
- 新的类型化数组的长度太大。
buffer的长度(如果length参数没有指定)或byteOffset不是新的类型化数组元素大小的整数倍。byteOffset不是有效的数组索引(0 和 253- 1 之间的整数)。- 当从一个缓冲区创建视图,边界在缓冲区之外。换句话说,
byteOffset + length * TypedArray.BYTES_PER_ELEMENT > buffer.byteLength。
静态属性
这些属性定义在TypedArray构造函数中,因此由所有TypedArray子类型共享。
get TypedArray[@@species]用于创建派生对象的构造函数。
所有TypedArray子类也有着以下静态属性:
TypedArray.BYTES_PER_ELEMENT返回不同的
TypedArray对象元素字节数的数值。TypedArray.name返回构造函数 name 的字符串值(例如
"Int8Array")。
静态方法
这些属性定义在TypedArray构造函数中,因此由所有TypedArray子类型共享。
TypedArray.from()从类数组或者可迭代对象创建新的
TypedArray。参见Array.from()。TypedArray.of()创建一个具有可变参数的
TypedArray。参见Array.of()。
实例属性
这些属性都是在TypedArray属性对象上定义的访问器属性(getter),因此由所有TypedArray子类型共享。
TypedArray.prototype.buffer返回类型化数组引用的
ArrayBuffer。TypedArray.prototype.byteLength返回类型化数组的长度(以字节为单位)。
TypedArray.prototype.byteOffset返回从类型化数组距离
ArrayBuffer起始位置的偏移量(以字节为单位)。TypedArray.prototype.length返回类型化数组中保存的元素个数。
所有TypedArray子类也有以下实例属性:
TypedArray.prototype.BYTES_PER_ELEMENT返回不同的
TypedArray对象元素大小的数字值。
实例方法
这些方法定义在TypedArray原型对象中,因此由所有TypedArray子类型共享。
TypedArray.prototype.at()(en-US)返回给定索引处的数组元素。接受从最后一项往回计算的负整数。
TypedArray.prototype.copyWithin()在数组内复制数组元素序列。参见
Array.prototype.copyWithin()。TypedArray.prototype.entries()返回一个新的数组迭代器对象,其中包含数组中每个索引的键/值对。参见
Array.prototype.entries()。TypedArray.prototype.every()如果调用数组中的每个元素都满足测试函数,则返回
true。参见Array.prototype.every()。TypedArray.prototype.fill()用静态值填充数组中从开始索引到结束索引的所有元素。参见
Array.prototype.fill()。TypedArray.prototype.filter()返回一个新数组,其中包含调用所提供的筛选函数返回为
true的所有数组元素。参见Array.prototype.filter()。TypedArray.prototype.find()返回数组中满足提供的测试函数的第一个元素的值,如果没有找到合适的元素,则返回
undefined。参见Array.prototype.find()。TypedArray.prototype.findIndex()返回数组中满足提供的测试函数的第一个元素的索引,如果没有找到合适的元素,则返回
-1。参见Array.prototype.findIndex()。TypedArray.prototype.findLast()(en-US)回数组中满足提供的测试函数的最后一个元素的值,如果没有找到合适的元素,则返回
undefined。参见Array.prototype.findLast()。TypedArray.prototype.findLastIndex()(en-US)返回数组中满足所提供测试函数的最后一个元素的索引,如果没有找到合适的元素,则返回
-1。参见Array.prototype.findLastIndex()。TypedArray.prototype.forEach()对调用数组中的每个元素调用函数。参见
Array.prototype.forEach()。TypedArray.prototype.includes()根据类型化数组是否包含一个确定的元素,来决定返回
true还是false参见Array.prototype.includes()。TypedArray.prototype.indexOf()返回在调用数组中可以找到给定元素的第一个(最小)索引,如果没有找到,则返回
-1。参见Array.prototype.indexOf()。TypedArray.prototype.join()将数组的所有元素连接为字符串。参见
Array.prototype.join()。TypedArray.prototype.keys()返回一个新的数组迭代器对象,该对象包含数组中每个索引的键。参见
Array.prototype.keys()。TypedArray.prototype.lastIndexOf()返回在调用数组中可以找到给定元素的最后一个(最大)索引,如果找不到,则返回
-1。参见Array.prototype.lastIndexOf()。TypedArray.prototype.map()返回一个新数组,其中包含对调用数组中的每个元素调用函数的结果。参见
Array.prototype.map()。TypedArray.prototype.reduce()对数组的每个元素(从左到右)执行用户提供的“reducer”回调函数,将其简化为单个值。参见
Array.prototype.reduce()。TypedArray.prototype.reduceRight()对数组的每个元素(从右到左)执行用户提供的“reducer”回调函数,将其简化为单个值。参见
Array.prototype.reduceRight()。TypedArray.prototype.reverse()反转数组元素的顺序——第一个成为最后一个,最后一个成为第一个。参见
Array.prototype.reverse()。TypedArray.prototype.set()在类型化数组中存储多个值,从指定数组读取输入值。
TypedArray.prototype.slice()提取调用数组的一部分并返回一个新数组。参见
Array.prototype.slice()。TypedArray.prototype.some()如果调用数组中至少有一个元素满足提供的测试函数,则返回
true。参见Array.prototype.some()。TypedArray.prototype.sort()对数组的元素进行排序并返回该数组。参见
Array.prototype.sort()。TypedArray.prototype.subarray()从给定的开始和结束的元素索引返回一个新的
TypedArray。TypedArray.prototype.values()返回一个新的数组迭代器对象,该对象包含数组中每个索引的值。参见
Array.prototype.values()。TypedArray.prototype.toLocaleString()返回一个表示调用数组及其元素的本地化字符串。参见
Array.prototype.toLocaleString()。TypedArray.prototype.toString()返回一个表示调用数组及其元素的字符串。参见
Array.prototype.toString()。TypedArray.prototype[@@iterator]()返回一个新的数组迭代器对象,该对象包含数组中每个索引的值。
示例
访问属性
你可以使用标准数组索引语法(即使用括号符号)引用数组中的元素。但是,在类型数组上获取或设置索引属性不会在原型链中搜索此属性,即使索引已越界。索引属性将查询ArrayBuffer并且永远不会查看对象属性。你仍然可以使用命名属性,就像所有对象一样。
// Setting and getting using standard array syntax const int16 = new Int16Array(2); int16[0] = 42; console.log(int16[0]); // 42 // Indexed properties on prototypes are not consulted (Fx 25) Int8Array.prototype[20] = "foo"; new Int8Array(32)[20]; // 0 // even when out of bound Int8Array.prototype[20] = "foo"; new Int8Array(8)[20]; // undefined // or with negative integers Int8Array.prototype[-1] = "foo"; new Int8Array(8)[-1]; // undefined // Named properties are allowed, though (Fx 30) Int8Array.prototype.foo = "bar"; new Int8Array(32).foo; // "bar"
不能被冻结
不是空的TypedArray不能被冻结,因为它们的底层ArrayBuffer可以通过缓冲区的另一个TypedArray视图进行变化。这意味着对象将从不会真正地冻结。
const i8 = Int8Array.of(1, 2, 3); Object.freeze(i8); // TypeError: Cannot freeze array buffer views with elements
byteOffset 必须对齐
当将TypedArray构建为ArrayBuffer的视图时,byteOffset参数必须与其元素大小对齐;换句话说,偏移量必须是BYTES_PER_ELEMENT的倍数。
const i32 = new Int32Array(new ArrayBuffer(4), 1); // RangeError: start offset of Int32Array should be a multiple of 4
const i32 = new Int32Array(new ArrayBuffer(4), 0);
byteLength 必须对齐
类似于byteOffset参数,ArrayBuffer传递给TypedArray构造函数的byteLength属性必须是构造函数BYTES_PER_ELEMENT的倍数。
const i32 = new Int32Array(new ArrayBuffer(3)); // RangeError: byte length of Int32Array should be a multiple of 4
const i32 = new Int32Array(new ArrayBuffer(4));
