1. TypedArray 与 ArrayBuffer
在 JavaScript 中, 它会将数组等数据存储于连续的内存区域中, 数据的类型和所占用的字节数也在这个过程中被确定。在 ES6 中, 添加了 TypedArray 数据类型来更好地支持二进制数据的处理。
TypedArray 可以看做是 ArrayBuffer 的视图, 它提供了类数组的操作方法, 能够以不同的数据类型访问 ArrayBuffer 的数据。一个 ArrayBuffer 对象表示的其实是一段连续的内存区域,可以直接操作内存。
下面是一个 TypedArray 的例子:
// 创建一个 ArrayBuffer 实例 const buffer = new ArrayBuffer(16); // 创建一个 Int16Array 实例 const int16Array = new Int16Array(buffer); // 设置 int16Array 索引为 0 的位置的数据为 1 int16Array[0] = 1;
2. DataView
DataView 实例是用来操作内存中的数据的,它提供了更加灵活的操作方式, 可以操作任意数据类型, 并且还可以指定字节序。因此, DataView 可以解决 TypedArray 无法指定字节序的问题。
下面是一个 DataView 的例子:
// 创建一个 ArrayBuffer 实例 const buffer = new ArrayBuffer(16); // 创建一个 DataView 实例 const dataView = new DataView(buffer); // 设置 dataView 索引为 0 的位置的 int16 数据为 1 dataView.setInt16(0, 1);
3. ArrayBuffer 的操作
3.1 获取一个 ArrayBuffer 对象的字节长度
在 JavaScript 中, 可以通过一个 ArrayBuffer 对象的 byteLength 属性获取其字节长度:
const buffer = new ArrayBuffer(16); console.log(buffer.byteLength); // 输出 16
3.2 截取一个 ArrayBuffer
截取 ArrayBuffer 时, 可以直接使用 slice() 方法, 返回一个从原始 ArrayBuffer 对象中指定起始位置和结束位置的新 ArrayBuffer 对象。
const buffer = new ArrayBuffer(16); const newBuffer = buffer.slice(4, 12); // 从 buffer 的第 4 字节开始截取,截取 8 个字节
3.3 拼接多个 ArrayBuffer
可以用 TypedArray 中的 set() 方法拼接多个 ArrayBuffer:
// 创建两个包含 int16 类型数据的 TypedArray 实例,每个实例有 2 个元素 const int16Array1 = new Int16Array([1, 2]); const int16Array2 = new Int16Array([3, 4]); // 创建一个新的 Int16Array 实例 const newInt16Array = new Int16Array(4); // 将 int16Array1 和 int16Array2 拼接起来 newInt16Array.set(int16Array1); newInt16Array.set(int16Array2, 2); // 第二个参数指定从 newInt16Array 的下标 2 开始拼接 console.log(newInt16Array); // 输出 [1, 2, 3, 4]
4. TypedArray 的操作
4.1 创建 TypedArray
TypedArray 对象可以通过传递一个 ArrayBuffer 实例来创建:
const buffer = new ArrayBuffer(16); const int32Array = new Int32Array(buffer);
4.2 设置 TypedArray 数据
可以将需要的数据直接赋值到 TypedArray 上:
const int16Array = new Int16Array([1, 2]); int16Array[0] = 3; console.log(int16Array[0]); // 输出 3
4.3 获取 TypedArray 数据
通过访问方法, 可以获取 TypedArray 对应位数的数据:
const int16Array = new Int16Array([1, 2]); console.log(int16Array[0]); // 输出 1
4.4 TypedArray 数据类型
在 TypedArray 中, 除了 Int8Array 之外的所有 TypedArray 类, 如 Int16Array、Uint16Array 等都支持以下数据类型:
- int8
- uint8
- int16
- uint16
- int32
- uint32
- float32
- float64
4.5 TypedArray 数据的字节长度
默认情况下, TypedArray 中每种数据类型的长度都是固定的, 可以通过 BYTES_PER_ELEMENT 静态属性获取。
const int16Array = new Int16Array([1, 2]); console.log(Int16Array.BYTES_PER_ELEMENT); // 输出 2
4.6 TypedArray 的迭代器
在 ES6 中, TypedArray 实现了 Symbol.iterator 接口, 因此可以使用 for of 循环遍历数组:
const int16Array = new Int16Array([1, 2]); for (let x of int16Array) { console.log(x); } // 输出 // 1 // 2
4.7 TypedArray 的其他方法
TypedArray 还提供了一些其他的方便方法:
- slice(start : number, end : number): 新的 TypedArray 实例,存储了原 TypedArray 从 start(包括 start)至 end(不包括 end)之间的元素。
- join(separator?: string): 将 TypedArray 使用指定的分隔符连接为字符串。
- reverse(): 将 TypedArray 中的元素以相反的顺序排列。
- sort(compareFn?): 将 TypedArray 中的元素按照指定的顺序排列。
5. DataView 的操作
5.1 获取 DataView 数据
DataView 实例通过访问方法获取对应类型的数据:
const buffer = new ArrayBuffer(16); const dataView = new DataView(buffer); // 设置 dataView 中下标为 0 的 int16 数据为 1 dataView.setInt16(0, 1); // 获取 dataView 中下标为 0 的 int16 类型的数据 console.log(dataView.getInt16(0));
5.2 设置 DataView 数据
DataView 实例通过设置方法设置对应类型的数据:
const buffer = new ArrayBuffer(16); const dataView = new DataView(buffer); // 设置 dataView 中下标为 0 的 uint8 类型数据为 255 dataView.setUint8(0, 255);
5.3 DataView 中获取和设置的数据类型
DataView 中可以获取和设置的数据类型如下:
- getInt8(): 8 位二进制有符号整数
- getUint8(): 8 位二进制无符号整数
- getInt16(): 16 位有符号整数
- getUint16(): 16 位无符号整数
- getInt32(): 32 位有符号整数
- getUint32(): 32 位无符号整数
- getFloat32(): 32 位浮点数
- getFloat64(): 64 位浮点数
6. 总结
ES12 中的 TypedArray 和 DataView 提供了一种方便、高效的操作二进制数据的方式。在实际应用中, 二者的选择通常由数据是固定长度还是不定长度、需要拼接合并的情况来决定, 以及需要类型控制的程度来选择。
希望本文对于阅读者更好地理解 TypedArray 和 DataView 的操作, 尤其是 buffer 操作方面,能够有一定的参考价值。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b5e6a9add4f0e0ffea321a