TypedArray - JavaScript 编辑
一个类型化数组(TypedArray)对象描述了一个底层的二进制数据缓冲区(binary data buffer)的一个类数组视图(view)。事实上,没有名为 TypedArray
的全局属性,也没有一个名为 TypedArray
的构造函数。相反,有许多不同的全局属性,它们的值是特定元素类型的类型化数组构造函数,如下所示。在下面的页面中,你会发现一些,与包含任何类型的元素的任意类型化数组一起使用的通用属性和方法。
语法
// 下面代码是语法格式,不能直接运行,
// TypedArray 关键字需要替换为底部列出的构造函数。
new TypedArray(); // ES2017中新增
new TypedArray(length);
new TypedArray(typedArray);
new TypedArray(object);
new TypedArray(buffer [, byteOffset [, length]]);
// TypedArray 指的是以下的其中之一:
Int8Array();
Uint8Array();
Uint8ClampedArray();
Int16Array();
Uint16Array();
Int32Array();
Uint32Array();
Float32Array();
Float64Array();
参数
length
- 当传入
length
参数时,一个内部的数组缓冲区会被创建在内存中,该缓存区的大小(类型化数组中byteLength
属性的值)是传入的length
乘以数组中每个元素的字节数(BYTES_PER_ELEMENT
),每个元素的值都为0
。(译者注:每个元素的字节数是由具体的构造函数决定的,比如Int16Array()
的每个元素的字节数为2
,Int32Array()
的每个元素的字节数为4
) typedArray
- 当传入一个任意类型化数组对象作为
typedArray
参数时(比如Int32Array
),typedArray
会被复制到一个新的类型数组中。typedArray
中的每个值在被复制到新的数组之前,会被转化为相应类型的构造函数。新的生成的类型化数组对象将会有跟传入的数组相同的长度(译者注:比如原来的类型化数组的length==2
,那么新生成的数组的length
也是2
,只是数组中的每一项进行了转化)。 object
当传入一个
object
作为参数时,就像通过TypedArray.from()
方法创建一个新的类型化数组一样。buffer
,byteOffset
,length
- 当传入一个
buffer
参数,或者再另外加上可选参数byteOffset
和length
时,一个新的类型化数组视图将会被创建,并可用于呈现传入的ArrayBuffer
实例。byteOffset
和length
参数指定了类型化数组视图将要暴露的内存范围。如果两者都未传入,那么整个buffer
都会被呈现;如果仅仅忽略length
,那么buffer
中偏移了byteOffset
后剩下的buffer
将会被呈现。
描述
ECMAScript 2015 定义了一个 TypeArray
构造器作为所有的类型化数组构造器(Int8Array
, Int16Array
等)的原型([[Prototype]]
)。该构造器并不会直接暴露出来:即没有全局的 %TypedArray%
和 TypeArray
属性,只能通过使用类似于 Object.getPrototypeOf(Int8Array.prototype
) 的方式直接访问。所有的类型化数组构造器都会继承 %
TypeArray%
构造器函数的公共属性和方法。此外,所有的类型化数组的原型(如 Int8Array.prototype
)都以 %TypeArray%.prototype
作为原型。
%TypedArray%
构造器自身不是特别有用,直接调用或使用 new
表达式实例化都会抛出一个TypeError
异常,除非在支持子类化(subclassing)创建对象的 JS 引擎下运行。但直到现在还没有这样的 JS 引擎出现。因此 %TypeArray%
仅仅在对所有的类型化数组构造器(Int8Array
等)的方法和属性进行 polyfill 的时候比较有用.
当创建一个 TypedArray
实例(如 Int8Array
)时,一个数组缓冲区将被创建在内存中,如果一个 ArrayBuffer
对象被当作参数传给构造函数,那么将使用传入的 ArrayBuffer
代替(即缓冲区被创建到 ArrayBuffer
中)。缓冲区的地址被存储在实例的内部属性中,并且所有 %TypedArray%.prototype
上的方法,例如 set value
和 get value
等,都会在这个数组缓冲区上进行操作。
属性访问
你可以使用标准数组索引语法获取类型化数组中的元素(也就是和访问普通数组元素一样,如 foo[1]
),然而,在类型化数组上获取或者设置属性的值时,并不会在这个属性的原型链中进行搜索,即使在索引超出了边界的时候。在原型中添加的属性将会在 ArrayBuffer
中查询而不是在对象的属性中。但是你依然可以像其他对象一样使用命名的属性来访问(foo.bar
的形式);具体见下面的例子:
// 使用标准数组语法来获取和设置属性值
var int16 = new Int16Array(2);
int16[0] = 42;
console.log(int16[0]); // 42
// 原型中添加的属性访问不到(此时索引值未超边界,20 < 32)
Int8Array.prototype[20] = "foo";
(new Int8Array(32))[20]; // 0
// 即使索引值超出了边界也一样不能访问(20 > 8)
Int8Array.prototype[20] = "foo";
(new Int8Array(8))[20]; // undefined
// 使用负数索引也不行
Int8Array.prototype[-1] = "foo";
(new Int8Array(8))[-1]; // undefined
// 但是可以使用命名属性的方式访问到
Int8Array.prototype.foo = "bar";
(new Int8Array(32)).foo; // "bar"
TypedArray 对象
类型 | 单个元素值的范围 | 大小(bytes) | 描述 | Web IDL 类型 | C 语言中的等价类型 |
---|---|---|---|---|---|
Int8Array | -128 to 127 | 1 | 8 位二进制有符号整数 | byte | int8_t |
Uint8Array | 0 to 255 | 1 | 8 位无符号整数(超出范围后从另一边界循环) | octet | uint8_t |
Uint8ClampedArray | 0 to 255 | 1 | 8 位无符号整数(超出范围后为边界值) | octet | uint8_t |
Int16Array | -32768 to 32767 | 2 | 16 位二进制有符号整数 | short | int16_t |
Uint16Array | 0 to 65535 | 2 | 16 位无符号整数 | unsigned short | uint16_t |
Int32Array | -2147483648 to 2147483647 | 4 | 32 位二进制有符号整数 | long | int32_t |
Uint32Array | 0 to 4294967295 | 4 | 32 位无符号整数 | unsigned long | uint32_t |
Float32Array | 1.2 ×10-38 to 3.4 ×1038 | 4 | 32 位 IEEE 浮点数(7 位有效数字,如 1.1234567 ) | unrestricted float | float |
Float64Array | 5.0 ×10-324 to 1.8 ×10308 | 8 | 64 位 IEEE 浮点数(16 有效数字,如 1.123...15 ) | unrestricted double | double |
BigInt64Array | -263 to 263-1 | 8 | 64 位二进制有符号整数 | bigint | int64_t (signed long long) |
BigUint64Array | 0 to 264-1 | 8 | 64 位无符号整数 | bigint | uint64_t (unsigned long long) |
属性
TypedArray.BYTES_PER_ELEMENT
- 返回一个数值,代表不同类型的类型化数组对象中,单个元素的字节大小。例如
new Int8Array().BYTES_PER_ELEMENT === 1
,new Int16Array().BYTES_PER_ELEMENT === 2
( 8 位字节为 1,16 位为 2 字节,类推)。 TypedArray.length
- 类型化数组中元素的个数,例如
new Int8Array(3).length === 3
。 TypedArray.name
- 返回一个字符串值,代表当前构造器的名称,例如
"Int8Array"
。 get TypedArray[@@species]
- 用于创建派生对象的构造函数函数。
TypedArray.prototype
TypedArray
对象的原型。
方法
TypedArray.from()
- 使用类数组(array-like)或迭代对象创建一个新的类型化数组.参见
Array.from()
. TypedArray.of()
- 通过可变数量的参数创建新的类型化数组.参见
Array.of()
.
TypedArray 原型
所有的类型化数组都继承自 TypedArray.prototype
.
属性
TypedArray.prototype.constructor
- 返回创建实例原型的构造函数.这是相应的typed array type的默认的构造函数.
TypedArray.prototype.buffer
只读- 返回被格式化数组引用的
ArrayBuffer
. 创建时已被固化,因此是只读的. TypedArray.prototype.byteLength
只读- 返回从
ArrayBuffer
读取的字节长度. 创建时已被固化,因此是只读的. TypedArray.prototype.byteOffset
只读- 返回从
ArrayBuffer
读取时的字节偏移量.创建时已被固化,因此是只读的. TypedArray.prototype.length
只读- 返回在类型化数组中的元素的数量.创建时已被固化,因此是只读的.
方法
TypedArray.prototype.copyWithin()
- 浅拷贝数组的部分元素到同一数组的不同位置,且不改变数组的大小,返回该数组. 参见
Array.prototype.copyWithin()
. TypedArray.prototype.entries()
- 返回一个
Array Iterator
对象,该对象包含数组中每一个索引的键值对.参见Array.prototype.entries()
. TypedArray.prototype.every()
- 测试数组的所有元素是否都通过了指定函数的测试. 参见
Array.prototype.every()
. TypedArray.prototype.fill()
- 将一个数组中指定区间的所有元素的值, 都替换成或者说填充成为某个固定的值. 参见
Array.prototype.fill()
. TypedArray.prototype.filter()
- 使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组. 参见
Array.prototype.filter()
. TypedArray.prototype.find()
- 返回一个满足提供的函数的测试的元素,若是没有满足的元素则返回
undefined
. 参见Array.prototype.find()
. TypedArray.prototype.findIndex()
- 查找数组中某指定元素的索引, 如果找不到指定的元素, 则返回 -1. 参见
Array.prototype.findIndex()
. 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.move()
未实现- 以前的不标准版本的
TypedArray.prototype.copyWithin()
. TypedArray.prototype.reduce()
- 接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值. 参见
Array.prototype.reduce()
. TypedArray.prototype.reduceRight()
- 接受一个函数作为累加器(accumulator),让每个值(从右到左,亦即从尾到头)缩减为一个值.(与
reduce()
的执行方向相反). 参见Array.prototype.reduceRight()
. TypedArray.prototype.reverse()
- 颠倒数组中元素的位置。第一个元素会成为最后一个,最后一个会成为第一个. 参见
Array.prototype.reverse()
. TypedArray.prototype.set()
- 读取一个指定数组中的元素保存到格式化数组中.
TypedArray.prototype.slice()
- 浅复制(shallow copy)数组的一部分到一个新的数组,并返回这个新数组. 参见
Array.prototype.slice()
. TypedArray.prototype.some()
- 数组中只要有一个元素满足提供的测试函数的测试就返回true,否则返回false. 参见
Array.prototype.some()
. TypedArray.prototype.sort()
- 对数组进行排序,并返回原数组(是改变原数组). 参见
Array.prototype.sort()
. TypedArray.prototype.subarray()
- 返回给定的起始和结束索引之间的元素组成的新的类型化数组.
TypedArray.prototype.values()
- 返回有数组中的元素组成的新的数组迭代对象. 参见
Array.prototype.values()
. TypedArray.prototype.toLocaleString()
- 返回一个将数组中的每个元素本地化后组成的字符串. 参见
Array.prototype.toLocaleString()
. TypedArray.prototype.toString()
- 返回一个由数组中的每个元素字符串化后组成的字符串. 参见
Array.prototype.toString()
. TypedArray.prototype[@@iterator]()
- 返回一个包含数组中每个元素的新的数组迭代对象.
方法的 Polyfill
大部分 TypedArray
s 中的方法可以使用 JavaScript 中的普通数组中存在的方法来实现。
下面的 JavaScript 代码片段,可能会是你尝试用来补救 TypedArray
方法缺失的手段(polyfill):
var typedArrayTypes = [Int8Array, Uint8Array, Uint8ClampedArray,
Int16Array, Uint16Array, Int32Array,
Uint32Array, Float32Array, Float64Array];
for (var k in typedArrayTypes)
for (var v in Array.prototype)
if (Array.prototype.hasOwnProperty(v) &&
!typedArrayTypes[k].prototype.hasOwnProperty(v))
typedArrayTypes[k].prototype[v] = Array.prototype[v];
规范
规范 | 状态 | 说明 |
---|---|---|
Typed Array Specification | Obsolete | Defined as TypedArray and ArrayBufferView interface with typed array view types. Superseded by ECMAScript 6. |
ECMAScript 2015 (6th Edition, ECMA-262) TypedArray Objects | Standard | Initial definition in an ECMA standard. Specified behaviour for indexed and named properties. Specified that new is required. |
ECMAScript (ECMA-262) TypedArray Objects | Living Standard |
浏览器支持
BCD tables only load in the browser
兼容性注意事项
从ECMAScript 2015 (ES6) 开始,TypedArray
构造函数使用的时候必须要使用 new
操作符,否则会抛出 TypeError
异常。
var dv = Int8Array([1, 2, 3]);
// TypeError: calling a builtin Int8Array constructor
var dv = new Int8Array([1, 2, 3]);
相关链接
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论