在前端开发中,我们经常需要处理二进制数据,如音频、视频、图片等。而 JavaScript 原生的数据类型并不支持二进制操作,因此 ES6 引入了新的数据类型 ArrayBuffer,用于处理二进制数据。
ArrayBuffer 简介
ArrayBuffer 是一种内存缓冲区,用于存储一段连续的二进制数据。它的大小是固定的,一旦创建就无法扩展或缩小。我们可以通过创建一个 ArrayBuffer 实例来分配一段指定大小的内存空间。
const buffer = new ArrayBuffer(16);
上面的代码创建了一个大小为 16 字节的 ArrayBuffer 对象。
ArrayBufferView
ArrayBufferView 是一组从 ArrayBuffer 对象中读取和写入数据的类型化数组。它们与 ArrayBuffer 对象之间的关系类似于 C 语言中的指针和数组之间的关系。
常见的 ArrayBufferView 类型有:
- Int8Array、Uint8Array、Uint8ClampedArray
- Int16Array、Uint16Array
- Int32Array、Uint32Array
- Float32Array、Float64Array
这些类型化数组提供了一些方法,用于读取和写入二进制数据。
const buffer = new ArrayBuffer(16); const int8View = new Int8Array(buffer); int8View[0] = 0x12; int8View[1] = 0x34; console.log(int8View[0]); // 18 console.log(int8View[1]); // 52
上面的代码创建了一个大小为 16 字节的 ArrayBuffer 对象,并使用 Int8Array 视图读写其中的数据。我们可以通过下标访问视图中的元素,也可以使用 set 和 get 方法读写多个元素。
const buffer = new ArrayBuffer(16); const int16View = new Int16Array(buffer); int16View.set([0x1234, 0x5678], 0); console.log(int16View); // Int16Array [ 4660, 22136 ] const value = int16View.get(0); console.log(value); // 4660
上面的代码使用 Int16Array 视图读写 ArrayBuffer 中的数据。set 方法用于写入多个元素,get 方法用于读取单个元素。
DataView
DataView 是一种通用的二进制数据读写接口,可以读写任意类型和任意字节序的数据。它与 ArrayBuffer 对象之间的关系类似于文件操作中的文件句柄和文件指针之间的关系。
const buffer = new ArrayBuffer(16); const dataView = new DataView(buffer); dataView.setUint8(0, 0x12); dataView.setUint8(1, 0x34); console.log(dataView.getUint16(0)); // 4660
上面的代码创建了一个大小为 16 字节的 ArrayBuffer 对象,并使用 DataView 接口读写其中的数据。我们可以使用 set 方法写入单个元素,也可以使用 get 方法读取多个元素。
底层实现
在底层实现中,ArrayBuffer 和 ArrayBufferView 类型化数组是由 C++ 代码实现的。具体来说,ArrayBuffer 对象是由 ArrayBufferObject 类实现的,它维护了一段连续的内存空间,并提供了一些方法用于读写其中的数据。
-- -------------------- ---- ------- ----- ----------------- - ------ -------- - ------- ------ ----- ------ -------------- - ----------- ------ ------------------ ---------- --- ------ ------------ ---- ---------- ------ ------------------ ---------- --- ----- ----- ------ ----------- ---- ---------- ------ ------------------ ----------------------- --- ------ ----------- ---- ---------- ------ ------------------ -------------- ---- ------ ----- -------- -------------- - --------------------------- - ------------------------- ------ ---- ----------------------------- ---------------- ------------- --------------- ------ ---- ------------------------------------ ---------------- --------- --------------- ------ ---- ------------ ---------------- ------------- -------- ------------------ ------ ---- ------------------- ---------------- --------- -------- ---- ------------- ------ ---- ---------------------------- ---------------- ------------- ----- -------------------- ---- ------------- ------ ---- ----------------------- ---------------- -------------- ------ ---- ------------------------------ ---------------- ---------- ------ ---- ---------------------------- ----------------- ------ ---- ----------------------- ----------------- ------ ---- ------------------------ - ------ ----- - ------ ---- ---------------------- -------------- ------ ------------ ----- - ------ --------- - ----- ------ ----- - ------ ------- - -------- ---------------------- ----------- ------- ---- ---------- ---------------------- ----------- ------ ------- ---- ---------- ----- ------- ------ --------- ---- ----------- --
上面的代码是 ArrayBufferObject 类的定义,它继承自 JSObject 类,表示一个 ArrayBuffer 对象。它有一个成员变量 m_data,表示分配的内存空间的指针,有一个成员变量 m_length,表示分配的内存空间的大小,有一个成员变量 m_isShared,表示是否是共享内存空间。
在底层实现中,ArrayBufferView 类型化数组是由 TypedArrayBase 类实现的,它继承自 JSObject 类,表示一个特定类型的视图。它有一个成员变量 m_buffer,表示关联的 ArrayBuffer 对象,有一个成员变量 m_byteOffset,表示视图在 ArrayBuffer 中的偏移量,有一个成员变量 m_length,表示视图的长度。
-- -------------------- ---- ------- ----------------- -------- ----- -------------- - ------ -------- - ------- ----- ---- - --------- ------ ----- -------- ----------- - --------------------- ------ ----- ---- ---------------- - -------------------------- ------ ---------- ------------------- --- --------------- ------------- ------- ---------- - ------ --------------------- ------------- ---------- ----------------------- ---------------- -------- - ----------------------- ------ ---------- ------------------- --- --------------- ------------- ------- ---------- ----- --------- --------- - ------ --------------------- ------------- ---------- --------- -------- - ------ ---------- ------------------- --- --------------- ------------- - ------ --------------------- ------------- --------- ----------------------- ---------------- -------- - ------ --------------- ---------------------- ------------- ---------- ---------- --------------------- ------- ------ ----------- ------ ------- - --- -- - ------------------- --------------- ------ - --- --------- -------------------------------------- ------------------ ----------- -------------------------- ---------------- ----------- -------- ------ ------- - ------ --------------- ---------------------- ------------- ---------- ---------- --------------------- ------- ------ ----------- - --- -- - ------------------- --------------- ------ - --- --------- -------------------------------------- ------------------ ----------- -------------------------- ---------------- ------------ ------ ------- - ------ --------------- ---------------------- ------------- ---------- ---------- --------------------- ------- - --- -- - ------------------- --------------- ------ - --- --------- -------------------------------------- ------------------ ----------- -------------------------- ----------------- ------ ------- - ------ --------------- ---------------------- ------------- ---------- ---------- ------ ------- - --- -- - ------------------- --------------- ------ - --- --------- -------------------------------------- ------------------ ----------- -------------------------- -------- ------ ------- - ------ --------------- ----------------------------------- ------------- ---------- ---------- ------ ------- - --- -- - ------------------- --------------- ------ - --- --------- -------------------------------------- ------------------ ----------- --------------------------------------- -------- ------ ------- - ------ ---- ----------------------------- ---------------- ------------- --------------- ------ ---- ------------------------------------ ---------------- --------- --------------- ------ ---- ------------ ---------------- ------------- -------- ------------------ ------ ---- ------------------- ---------------- --------- -------- ---- ------------- ------ ---- ---------------------------- ---------------- ------------- ----- -------------------- ---- ------------- ------ ---- ----------------------- ---------------- -------------- ------ ---- ------------------------------ ---------------- ---------- ------ ---- ---------------------------- ----------------- ------ ---- ----------------------- ----------------- ------ ---- ------------------------ - ------ ----- - ------------ -------- ----- - ------ --------------- - ------ ------------ ----- - ------ ------------- - ------ ------------ ----- - ------ -------- - ------------ - ------ -------- ----- - ------ --------- - ------ ---------- ----- - ------ ------------- - ----------------- -- -- ------ ----- - ------ ------------------------------------------------------------ - -------------- - ---- ---------- ----- - ------ --------------------- - ---------- ------------------ --- ---------- ---------- - -------- ---------- - ----------- - --------------- - ------------------------- - ---- ------------------ --- --------------------- ------- ------ ----------- ------ ------- - ------------------------- -------- - ---------------- ------------ - ----------- -------- - ------- ------------------- - -------- - ----------- -- ------------------------------ - ---- ------------------ --- --------------------- ------- ------ ----------- - ------------------------- -------- - ---------------- ------------ - ----------- -------- - ----------------------- - ------------- - ------------ ------------------- - -------- - ----------- -- ------------------------------ - ---- ------------------ --- --------------------- ------- - ------------------------- -------- - ---------------- ------------ - -- -------- - ---------------------- - ------------ ------------------- - -------- - ----------- -- ------------------------------ - ---- ------------------ --- ------ ------- - ------------------------- -------- - -------------------------- - ------------- ------------ - -- -------- - ------- ------------------- - -------- - ----------- -- ------------------------------ - ---- ------------------------------- --- ------ ------- - ------------------------- -------- - --------------------------------------- - ------------- ------------ - -- -------- - ------- ------------------- - -------- - ----------- -- ------------------------------ - ------ ---- ---------------------- -------------- ------------------- --------- ------ --------- ------ ------------- --
上面的代码是 TypedArrayBase 类的定义,它是 TypedArray 类的基类,表示一个类型化数组。它有一个成员变量 m_buffer,表示关联的 ArrayBuffer 对象,有一个成员变量 m_byteOffset,表示视图在 ArrayBuffer 中的偏移量,有一个成员变量 m_length,表示视图的长度。
总结
ES6 中的 ArrayBuffer 是一种内存缓冲区,用于存储一段连续的二进制数据。它提供了类型化数组和通用的 DataView 接口,用于读写二进制数据。在底层实现中,ArrayBuffer 和 ArrayBufferView 类型化数组是由 C++ 代码实现的,它们与 JavaScript 代码之间通过 V8 引擎提供的 API 进行交互。掌握 ArrayBuffer 和 ArrayBufferView 的使用方法和底层实现原理,对于处理二进制数据的前端开发非常有帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/65ca32c5add4f0e0ff413e42