arraybuffer操作_ArrayBuffer笔记

本文详细介绍了JavaScript中的ArrayBuffer及其与二进制数据操作相关的TypedArray视图和DataView视图。ArrayBuffer对象用于存储二进制数据,而TypedArray视图和DataView视图则提供了对这些数据的访问和操作方式。文中讲解了ArrayBuffer的创建、视图的使用、以及不同类型的 TypedArray 视图。此外,还讨论了字节序、溢出处理、以及在WebSocket、Fetch API、File API中的应用。最后,提到了SharedArrayBuffer和Atomics对象在多线程环境中的重要性。
摘要由CSDN通过智能技术生成

前言

全文摘抄自阮一峰的<>,单纯作为笔记使用

ArrayBuffer

Arraybuffer对象, TypedArray视图和DataView视图是Javascript 操作二进制数据的一个接口它们都是以数组的语法处理二进制数据,所以统称为二进制数组.

这个接口原始设计目的与WebGL项目有关,即浏览器与显卡之间的通信接口,为了满足Javascript与显卡1大量的,实时的数据交换,它们之间的通信必须是二进制的,而不能是传统的文本格式(文本格式传递一个32位整数,两端都要进行格式转换将非常耗时)

二进制数组组成

ArrayBuffer对象

代表内存之中的一段二进制数据,可以通过"视图"进行操作,"视图"部署了数组接口,意味着可以用数组方法操作内存

TypedArray视图

共9种类型视图,下面会提到

DataView视图

可以自定义复合格式的视图,自定义字节序

总结

ArrayBuffer: 代表原始的二进制数据

TypedArray: 读写简单类型的二进制数据

DataView: 读写复杂类型的二进制数据

ArrayBuffer对象

ArrayBuffer也是一个构造函数,可以分配一段可以存放数据的连续内存区域。

const buf = new ArrayBuffer(32);

上面代码生成了一段 32 字节的内存区域,每个字节的值默认都是 0。可以看到,ArrayBuffer构造函数的参数是所需要的内存大小(单位字节)。

DataView

为了读写这段内容,需要为它指定视图。DataView视图的创建,需要提供ArrayBuffer对象实例作为参数。

const dataView = new DataView(buf);

dataView.getUint8(0) // 0

上面代码对一段 32 字节的内存,建立DataView视图,然后以不带符号的 8 位整数格式,从头读取 8 位二进制数据,结果得到 0,因为原始内存的ArrayBuffer对象,默认所有位都是 0

TypedArray

与DataView视图的一个区别是,它不是一个构造函数,而是一组构造函数,代表不同的数据格式。

const buffer = new ArrayBuffer(12);

const x1 = new Int32Array(buffer);

x1[0] = 1;

const x2 = new Uint8Array(buffer);

x2[0] = 2;

x1[0] // 2

上面代码对同一段内存,分别建立两种视图:32 位带符号整数(Int32Array构造函数)和 8 位不带符号整数(Uint8Array构造函数)。由于两个视图对应的是同一段内存,一个视图修改底层内存,会影响到另一个视图。

TypedArray视图的构造函数,除了接受ArrayBuffer实例作为参数,还可以接受普通数组作为参数,直接分配内存生成底层的ArrayBuffer实例,并同时完成对这段内存的赋值。

const typedArray = new Uint8Array([0,1,2]);

typedArray.length // 3

typedArray[0] = 5;

typedArray // [5, 1, 2]

实例属性方法

ArrayBuffer.prototype.byteLength: 返回所分配的内存区域的字节长度

ArrayBuffer.prototype.slice(): 允许将内存区域的一部分,拷贝生成一个新的ArrayBuffer对象

ArrayBuffer.isView(): 表示参数是否为ArrayBuffer的视图实例(TypedArray实例或DataView实例)

TypedArray 视图

与普通数组类似,差异在于:

TypedArray 数组的所有成员,都是同一种类型。

TypedArray 数组的成员是连续的,不会有空位。

TypedArray 数组成员的默认值为 0。

TypedArray 数组只是一层视图,本身不储存数据,它的数据都储存在底层的ArrayBuffer对象之中,要获取底层对象必须使用buffer属性。

共9种视图类型

数据类型

字节长度

含义

对应的 C 语言类型

Int8

1

8 位带符号整数

signed char

Uint8

1

8 位不带符号整数

unsigned char

Uint8C

1

8 位不带符号整数(自动过滤溢出)

unsigned char

Int16

2

16 位带符号整数

short

Uint16

2

16 位不带符号整数

unsigned short

Int32

4

32 位带符号整数

int

Uint32

4

32 位不带符号的整数

unsigned int

Float32

4

32 位浮点数

float

Float64

8

64 位浮点数

double

构造函数有多种用法

(1)TypedArray(buffer, byteOffset=0, length?)

第一个参数(必需):视图对应的底层ArrayBuffer对象。

第二个参数(可选):视图开始的字节序号,默认从 0 开始。

第三个参数(可选):视图包含的数据个数,默认直到本段内存区域结束。

// 创建一个8字节的ArrayBuffer

const b = new ArrayBuffer(8);

// 创建一个指向b的Int32视图,开始于字节0,直到缓冲区的末尾

const v1 = new Int32Array(b);

// 创建一个指向b的Uint8视图,开始于字节2,直到缓冲区的末尾

const v2 = new Uint8Array(b, 2);

// 创建一个指向b的Int16视图,开始于字节2,长度为2

const v3 = new Int16Array(b, 2, 2);

注意,byteOffset必须与所要建立的数据类型一致,否则会报错。

const buffer = new ArrayBuffer(8);

const i16 = new Int16Array(buffer, 1);

// Uncaught RangeError: start offset of Int16Array should be a multiple of 2

(2)TypedArray(length)

不通过ArrayBuffer对象,直接分配内存而生成

const f64a = new Float64Array(8);

f64a[0] = 10;

f64a[1] = 20;

f64a[2] = f64a[0] + f64a[1];

(3)TypedArray(typedArray)

接受另一个TypedArray实例作为参数, 此时生成的新数组,只是复制了参数数组的值,对应的底层内存是不一样的。新数组会开辟一段新的内存储存数据,不会在原数组的内存之上建立视图。

const x = new Int8Array([1, 1]);

const y = new Int8Array(x);

x[0] // 1

y[0] // 1

x[0] = 2;

y[0] // 1

如果想基于同一段内存,构造不同的视图,可以采用下面的写法

const x = new Int8Array([1, 1]);

const y = new Int8Array(x.buffer);

x[0] // 1

y[0] // 1

x[0] = 2;

y[0] // 2

(4)TypedArray(arrayLikeObject)

参数是一个普通数组直接生成TypedArray实例, 这时TypedArray视图会重新开辟内存,不会在原数组的内存上建立视图

const typedArray = new Uint8Array([1, 2, 3, 4]);

TypedArray 数组也可以转换回普通数组

const normalArray = [...typedArray];

// or

const normalArray = Array.from(typedArray);

// or

const normalArray = Array.prototype.slice.call(typedArray);

数组方法

普通数组的操作方法和属性,对 TypedArray 数组完全适用

TypedArray.prototype.copyWithin(target, start[, end = this.length])

TypedArray.prototype.entries()

TypedArray.prototype.every(callbackfn, thisArg?)

TypedArray.prototype.fill(value, start=0, end=this.length)

TypedArray.prototype.filter(callbackfn, thisArg?)

TypedArray.prototype.find(predicate, thisArg?)

TypedArray.prototype.findIndex(predicate, thisArg?)

TypedArray.prototype.forEach(callbackfn, thisArg?)

TypedArray.prototype.indexOf(searchElement, fromIndex=0)

TypedArray.prototype.join(separator)

TypedArray.prototype.keys()

TypedArray.prototype.lastIndexOf(searchElement, fromIndex?)

TypedArray.prototype.ma

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值