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() 的每个元素的字节数为 2Int32Array() 的每个元素的字节数为 4)
typedArray
当传入一个任意类型化数组对象作为 typedArray 参数时(比如 Int32Array),typedArray 会被复制到一个新的类型数组中。typedArray 中的每个值在被复制到新的数组之前,会被转化为相应类型的构造函数。新的生成的类型化数组对象将会有跟传入的数组相同的长度(译者注:比如原来的类型化数组的 length==2,那么新生成的数组的 length 也是 2,只是数组中的每一项进行了转化)。
object

当传入一个 object 作为参数时,就像通过 TypedArray.from() 方法创建一个新的类型化数组一样。

bufferbyteOffset, 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 valueget 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 12718 位二进制有符号整数byteint8_t
Uint8Array0 to 25518 位无符号整数(超出范围后从另一边界循环)octetuint8_t
Uint8ClampedArray0 to 25518 位无符号整数(超出范围后为边界值)octetuint8_t
Int16Array-32768 to 32767216 位二进制有符号整数shortint16_t
Uint16Array0 to 65535216 位无符号整数unsigned shortuint16_t
Int32Array-2147483648 to 2147483647432 位二进制有符号整数longint32_t
Uint32Array0 to 4294967295432 位无符号整数unsigned longuint32_t
Float32Array1.2×10-38 to 3.4×1038432 位 IEEE 浮点数(7 位有效数字,如 1.1234567unrestricted floatfloat
Float64Array5.0×10-324 to 1.8×10308864 位 IEEE 浮点数(16 有效数字,如 1.123...15)unrestricted doubledouble
BigInt64Array-263 to 263-1864 位二进制有符号整数bigintint64_t (signed long long)
BigUint64Array0 to 264-1864 位无符号整数bigintuint64_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

大部分 TypedArrays 中的方法可以使用 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 SpecificationObsoleteDefined as TypedArray and ArrayBufferView interface with typed array view types. Superseded by ECMAScript 6.
ECMAScript 2015 (6th Edition, ECMA-262)
TypedArray Objects
StandardInitial 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:146 次

字数:31494

最后编辑:4年前

最近更新:JSmiles

编辑次数:1 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文