JavaScript 中的 `ArrayBuffer`

JavaScript 中的 `ArrayBuffer`

本文介紹 JavaScript 中的 ArrayBuffer

我們將從基礎到使用方法、相關類型以及實際應用,全面講解 ArrayBuffer

YouTube Video

JavaScript 中的 ArrayBuffer

JavaScript 的 ArrayBuffer 是用於處理低層二進位數據的物件,特別適用於操作 WebAPI、文件操作及網路通訊中的二進位數據。

ArrayBuffer 是什麼?

ArrayBuffer 是一種用來處理固定長度二進位數據的資料結構。它允許處理普通 JavaScript 陣列或物件無法處理的原始二進位數據。

ArrayBuffer 本身無法直接操作數據。而是通過基於 ArrayBufferTypedArrayDataView 來讀寫數據。

ArrayBuffer 特別適用於以下情況:。

  • 處理從網路接收到的二進位數據時
  • 當需要在 Web Worker 中高效共享數據時。
  • 在使用 Canvas 或 WebGL 進行圖像處理或 3D 渲染時。
  • 在處理文件(特別是二進位文件)時。

建立 ArrayBuffer

首先,讓我們從如何建立一個 ArrayBuffer 實例開始。ArrayBuffer 以位元組單位分配記憶體,因此需要在建立時指定大小。

1const buffer = new ArrayBuffer(16); // Create a 16-byte buffer
2console.log(buffer.byteLength); // 16
  • 在此範例中,分配了一個 16 位元組大小的緩衝區。此緩衝區尚未包含任何數據。

使用 TypedArray 操作數據

你無法直接訪問 ArrayBuffer,因此需要使用 TypedArray 來讀寫數據。TypedArray 提供了例如 Int8ArrayFloat32Array 等不同類型的視圖,允許高效訪問二進位數據。

使用 Int8Array 的範例

1const buffer = new ArrayBuffer(8); // Create an 8-byte buffer
2const int8View = new Int8Array(buffer); // Create an Int8Array
3
4int8View[0] = 42; // Write data to the first byte
5console.log(int8View[0]); // 42
  • Int8Array 可以在每個位元組中存儲數據,使得緩衝區能容納 8 個元素。通過使用不同類型的視圖,可以高效地操作數據。

其他 TypedArray 的範例

JavaScript 提供各種類型的 TypedArray。例如,若要處理 32 位元無符號整數,可以使用 Uint32Array

1const buffer = new ArrayBuffer(16);
2const uint32View = new Uint32Array(buffer);
3
4uint32View[0] = 123456;
5console.log(uint32View[0]); // 123456
  • Uint32Array 能以 4 字節為單位儲存資料,因此緩衝區可以容納四個元素。根據處理的數據類型選擇適當的 TypedArray 是非常重要的。

使用 DataView 靈活地操作數據

TypedArray 只能處理固定類型的數據,但使用 DataView,可以將任何類型的數據寫入任何位置。這在處理包含混合數據類型的緩衝區時特別有用。

 1const buffer = new ArrayBuffer(16);
 2const dataView = new DataView(buffer);
 3
 4// Write a 32-bit signed integer to byte 0
 5dataView.setInt32(0, 2147483647);
 6console.log(dataView.getInt32(0)); // 2147483647
 7
 8// Write a 16-bit unsigned integer to byte 4
 9dataView.setUint16(4, 65535);
10console.log(dataView.getUint16(4)); // 65535

使用 DataView 時,可以指定位元組偏移量,並讀寫各種類型的數據。這在處理如網絡協議或文件格式這樣的複雜二進位結構時非常有用。

需要考慮的位元組順序(Endianness)

使用 DataView 時還需要注意位元組順序(Endianness)。根據計算機架構的不同,數據在記憶體中的存儲順序可能有所不同。DataView 方法提供選項可用於指定位元組順序。

1const buffer = new ArrayBuffer(4);
2const view = new DataView(buffer);
3
4// Write a 32-bit integer in little-endian format
5view.setInt32(0, 42, true); // true indicates little-endian
6console.log(view.getInt32(0, true)); // 42

如果未指定正確的位元組順序,數據可能無法在不同環境中正確解析,因此在進行網絡通信或文件操作時需要特別注意。

ArrayBuffer 的應用

ArrayBuffer 是一種強大的工具,常用於網頁開發和瀏覽器 API 中。讓我們來看一些應用範例。

接收與處理二進位數據

例如,可以使用 XMLHttpRequestfetch API 從伺服器獲取二進位數據,並將其作為 ArrayBuffer 處理。

1fetch('https://codesparklab.com/image.jpg')
2    .then(response => response.arrayBuffer())
3    .then(buffer => {
4        const view = new Uint8Array(buffer);
5        console.log(view);
6    });
  • 在此範例中,圖像數據從服務器獲取,並以 Uint8Array 的形式處理。通過這種方式,可以使用 ArrayBuffer 處理從伺服器接收到的數據。

在 WebGL 中的用法

在 WebGL 中,ArrayBuffer 被用於高效處理頂點數據和顏色數據等二進位數據。

 1const vertices = new Float32Array([
 2    -1.0, -1.0,
 3    1.0, -1.0,
 4    1.0,  1.0,
 5    -1.0,  1.0
 6]);
 7
 8// Send data to the WebGL buffer
 9const buffer = gl.createBuffer();
10gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
11gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  • 在此範例中,使用 Float32Array 定義矩形的頂點座標,並將其傳遞到 WebGL 緩衝區。

記憶體管理與 ArrayBuffer

ArrayBuffer 在位元組層級管理記憶體,非常高效,但同時也需要小心管理記憶體。處理大型二進位數據時,正確釋放未使用的 ArrayBuffer 是很重要的。雖然 JavaScript 會自動執行垃圾回收,但如果 ArrayBuffer 持續被引用,可能會導致記憶體洩漏。

總結

ArrayBuffer 是 JavaScript 中處理二進位數據的基礎。結合 TypedArrayDataView,可以高效且靈活地處理二進位數據。它們是網頁開發中不可或缺的工具,特別是在涉及處理如網路通信和 WebGL 的二進位數據的多種情況下。通過正確理解並適當使用它們,可以提升性能和效率。

您可以在我們的 YouTube 頻道上使用 Visual Studio Code 來跟隨上述文章一起學習。 請也查看我們的 YouTube 頻道。

YouTube Video