ArrayBuffer、TypedArray与DataView

3,262 阅读3分钟

背景

因为需要处理一些二进制字符串的问题,接触到了ArrayBuffer,进而对TypedArray和DataView做了一些研究。

ArrayBuffer(数组缓存区)

ArrayBuffer是为了处理二进制数据流而出现的,但是JS没有办法直接处理(读写)它里面的内容,于是就需要 TypedArray

初始化对象

new ArrayBuffer(length)

length: 要创建的ArrayBuffer的大小,以字节为单位。

应用场景

  • Websocket
  • Ajax/Fetch
  • Canvas
  • 读取本地文件
  • 解码/编码base64、计算文件MD5

TypedArray(类型化数组)

TypedArray是一个描述 ArrayBuffer 的类数组视图,虽然并没有一个 TypedArray 的全局属性和构造器,但是提供了一系列基于它的特定数据类型的数组(可以理解为 TypedArray 是interface而它们扩展的类)。TypedArray拥有一起Array的方法和属性以及操作方式,唯一不同在于指定了元素的类型,当给元素赋予不同类型的值且类型转换失败,则赋值失败置0。

  • Int8Array
  • Uint8Array
  • Uint8ClampedArray
  • Int16Array
  • Uint16Array
  • Int32Array
  • Uint32Array
  • Float32Array
  • Float64Array

初始化对象

new TypedArray(); // new in ES2017
new TypedArray(length);
new TypedArray(typedArray);
new TypedArray(object);
new TypedArray(buffer [, byteOffset [, length]]);

length: 要创建的数组长度,所占的字节等于长度乘以数组属性 BYTES_PER_ELEMENT (该属性根据数组的类型而定,如Int8Array的元素占1个字节,Float32Array的占4个字节)

typedArray: 把另一个typedArray对象的每一个元素转换为新typedArray对象的类型

object: 把一个类数组的对象(array或iterator)转换为typedArray对象

buffer: ArrayBuffer对象,如果ArrayBuffer对象的字节长度与本TypedArray的单个元素字节长队无法整除,则会报错

byteOffset: 指定ArrayBuffer对象中的暴露给typedArray的起始位置(以字节为单位)

length: 指定ArrayBuffer对象中的暴露给typedArray字节数

DataView(数据视图)

DataView是一个比TypedArray更加灵活更接近底层的操作二进制数据的视图对象。

初始化对象

new DataView(buffer [, byteOffset [, byteLength]])

buffer: ArrayBuffer对象

byteOffset: 指定ArrayBuffer对象中的暴露给typedArray的起始位置(以字节为单位)

byteLength: 指定ArrayBuffer对象中的暴露给typedArray字节数

常用Read/Write方法

  • getInt8/setInt8
  • getUint8/setUint8
  • getInt16/setInt16
  • getUint16/setUint16
  • getInt32/setInt32
  • getUint32/setUint32
  • getFloat32/setFloat32
  • getFloat64/setFloat64

Read方法,都包含byteOffset参数,表示读取位置,以字节为单位;除了Int8和Uint8以外的方法还带有可选参数littleEndian,true代表使用小端序,false或不传参则使用大端序。

Write方法,都包含byteOffset参数,表示写入位置,以字节为单位;value参数代表要设置的值;除了Int8和Uint8以外的方法还带有可选参数littleEndian,true代表使用小端序,false或不传参则使用大端序。

关于端序Endian

是指连续字节码在内存中的存储顺序(所以1字节的变量不存在端序问题)。其中,

  • 大端序: 先存高位
  • 小端序: 先存低位

需要特别说明的是,不同的机器的存储顺序并不相同,而TypedArray是使用当前运行环境的存储顺序。

浏览器支持

前面介绍的3个类为JS提供了一直所缺乏的操作底层数据的工具和接口,使得JS能在更多的业务场景有所发挥。

下面是目前主流的PC和移动端浏览器的兼容情况,总体而言,绝大多数的现代浏览器都已经很好的支持这一新的功能。

ta

参考资料

MDN-ArrayBuffer

MDN-TypedArray

MDN-DataView

wikipedia-字节串(Endianness)