浅谈JavaScript中的ArrayBuffer

浅谈JavaScript中的ArrayBuffer

什么是ArrayBuffer

ArrayBuffer是一个用于存储二进制数据的类,它提供了一种方法来表示字节序列,这些字节可以表示各种数据类型,如整数、浮点数、字符串等。ArrayBuffer是一个不可变的数据结构,它不能被修改,但可以通过创建一个TypedArray或DataView来修改它的内容。

知识点
  1. 对内存中固定长度的、连续的、二进制数据的、引用
  2. ArrayBuffer要当做Buffer理解,不能当做Array理解,因为它不具备任何Array的常用的方法;叫ArrayBuffer估计是因为它表示的是内存中连续的数据。
  3. ArrayBuffer的大小固定,不能动态扩展。
  4. ArrayBuffer不能直接操作,需要使用TypedArray或DataView来操作。

花式操作ArrayBuffer

ArrayBuffer不能直接操作,需要使用TypedArray或DataView来操作。三者关系如下:

ArrayBuffer、TypedArray、DataView关系

TypedArray

TypedArray 是一组用于操作 ArrayBuffer 的类型化数组。 它们允许你以特定的数据类型(例如:整数、浮点数)来读取和写入 ArrayBuffer 中的数据。包含如下类型:

  1. 1. Int8Array: 8 位有符号整数数组。
  2. 2. Uint8Array: 8 位无符号整数数组。
  3. 3. Uint8ClampedArray: 8 位无符号整数数组,但当赋值超出范围时会被自动调整到 0 或 255。
  4. 4. Int16Array: 16 位有符号整数数组。
  5. 5. Uint16Array: 16 位无符号整数数组。
  6. 6. Int32Array: 32 位有符号整数数组。
  7. 7. Uint32Array: 32 位无符号整数数组。
  8. 8. Float32Array: 32 位浮点数数组。
  9. 9. Float64Array: 64 位浮点数数组。

TypedArray 还有set、subarray等方法,但没有spliceconcat方法。具体可查阅相关文档。

使用TypedArray操作ArrayBuffer
let buffer = new ArrayBuffer(16);
    console.log(buffer); // 长度16
    let int8 = new Int8Array(buffer);
    console.log(int8); // 长度16
    let int16 = new Int16Array(buffer);
    console.log(int16); // 长度8
    let int32 = new Int32Array(buffer);
    console.log(int32); // 长度4
    let float64 = new Float64Array(buffer);
    console.log(float64); // 长度2

结合这个图理解上面代码的运行结果

不同的TypedArray的赋值操作

由上图可以知道,ArrayBuffer的长度和Uint8Array的长度是相同的,所以可以认为对Uint8Array的操作和ArrayBuffer对应位置一一对应,不再赘述。

let buffer = new ArrayBuffer(16);
    let uint8 = new Uint8Array(buffer);
    uint8[0] = 255;
    console.log(uint8,uint8.buffer);

以Unit16为例,一个Unit16占两个字节,一个字节8个bit;而ArrayBuffer一个位置对应一个字节.所以当uint16[0] = 258时,其16个bit位为:00000001 00000010,存储在ArrayBuffer中时,会占据两个字节的位置[2,1],

let buffer = new ArrayBuffer(2);
    /*let uint8 = new Uint8Array(buffer);
    uint8[0] = 255;
    console.log(uint8,uint8.buffer);*/
    let uint16 = new Uint16Array(buffer);
    uint16[0] = 258;
    console.log(uint16,uint16.buffer);// [258] , [2,1]

需要注意的对应的位置,从二进制数的低位开始,每8个bit位对应一个字节,可以参考下图理解:

32位、64位同理,大家可以尝试一下。

DataView

DataView 提供了更灵活的方式来读取和写入 ArrayBuffer 中的数据。 它可以让你以任意字节偏移量和数据类型来访问数据,而无需像 TypedArray 那样必须从缓冲区的开头开始。

let buffer = new ArrayBuffer(4);
let dv = new DataView(buffer);
dv.setUint16(1,258); 
console.log(dv.getUint16(1),dv.getUint16(0),dv.buffer);// 输出258,1,[0,1,2,0];

DataView 根据不同的方法决定操作的字节数,以上述的setUint16(1,258)为例,表示从索引为1的位置开始,操作连续两个字节的数据,数据范围为0-65535,258的二进制为00000001 00000010,所以这两个字节为[1,2];getUint16(1),表示从索引1开始连续读两个字节[00000001,00000010],所以输出为258;getUint16(0),表示从索引0开始连续读两个字节[00000000,00000001],所以输出为1。整个ArrayBuffer为[0,1,2,0],可以发现,填入的顺序和TypedArray的顺序是相反的。32位、64位大家可以自行尝试一下。可以参考下图理解:

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值