[JS] ArrayBuffer、DataView和TypedArray
JavaScript 中數組元素的數據類型是不固定的,number 類型可以是整數也可以是浮點數。這種性質與其它常見語言中的定型數組很不一樣,導致不同語言編寫的程序在交換數據的時候,需要花費很多時間在數據轉換上。
ECMAScript 后來引入了定型數組 TypedArray。TypedArray并不是一個實際存在的數據類型,而是一系列定型數組類型的統稱,它包含了 Int8Array、Uint8Array、Int16Array、Uint16Array、Float32Array等等。
這些定型數組只是一種“視圖”,通過一種指定的方式解讀內存中的二進制數據。
ArrayBuffer
在 JavaScript 中,可以通過 ArrayBuffer 預分配內存。
const buffer = new ArrayBuffer(16); // 分配 16 個字節
ArrayBuffer 在分配之后就不能再調整大小,可以通過 slice 方法切片出小 buffer。
ArrayBuffer 的粒度為字節 byte,不是比特 bit。
ArrayBuffer 不能直接讀寫,要通過視圖讀寫。視圖指的是 DataView 或者 TypedArray。
ArrayBuffer 存儲的是二進制,只是一堆數據,但是數據表達了什么信息是未定義的。我們需要一種“解讀方式”,按照一定的規定,才能解讀出信息。不同的解讀方式可以解讀出不同的信息。這里的解讀方式就是視圖,也就是 DataView 或者 TypedArray。
如下圖:

TypedArray
定型數組用于指定一種方式來讀寫一塊buffer。
常見的類型有:
| ElementType | 字節 | 說明 | 等價的C類型 |
|---|---|---|---|
| Int8 | 1 | 8位有符號整數 | signed char |
| Uint8 | 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位IEEE-754浮點數 | float |
| Float64 | 8 | 64位IEEE-754浮點數 | double |
創建定型數組的時候,可以指定一個 ArrayBuffer 對象,那么定型數組實例會基于已存在的內存空間創建。
如果不指定已有的 ArrayBuffer 對象,則需要指定定型數組的長度,會自動在內存中分配內部數組緩沖區。
DataView
TypedArray是定型數組,在指定類型之后,就只能以固定大小的“窗口”來觀察二進制讀出一個數字來。
而 DataView 是一種更靈活的 buffer 視圖,它可以通過指定偏移量和 elementType 在 buffer 中的任意位置讀寫一塊數據。
它的特點有:
- 必須指定 ArrayBuffer 實例才能創建 DataView 實例。
- 可以指定字節序。
- 讀寫操作超出邊界時,會報錯 RangeError。
應用場景
ArrayBuffer 的關鍵字是二進制、通信。
常見的應用場景如下:
- 處理二進制文件: 讀取、修改、生成二進制文件(如圖像、音頻、視頻等)。
- WebSocket 數據傳輸: 傳輸二進制數據,如視頻流、音頻數據等。
- WebGL 與圖形處理: 存儲和傳遞圖形數據到 GPU,處理頂點、顏色值等。
- 音頻處理: 生成或修改音頻數據,通過 Web Audio API 進行處理。

浙公網安備 33010602011771號