本文介紹了 JavaScript 中 ArrayBuffer 和 TypedArray 的應用。ArrayBuffer 用於預分配記憶體,存儲二進位數據,但需通過 DataView 或 TypedArray 視圖來讀寫。TypedArray 是定型數組,用於高效處理特定數據類型。DataView 則提... ...
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 進行處理。