背景
因为需要处理一些二进制字符串的问题,接触到了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和移动端浏览器的兼容情况,总体而言,绝大多数的现代浏览器都已经很好的支持这一新的功能。