JavaScript ArrayBuffer
1. ArrayBuffer とは?
ArrayBuffer は、固定されたメモリブロックであり、多くの場合「型付き配列(Typed Arrays)」を格納するために使用されます。
このブロックの上に、ビットを数値、バイト、またはその他のデータ型として解釈するさまざまなビュー(Views)を作成できます。
2. ArrayBuffer の生成
新しい ArrayBuffer を作成するには、new ArrayBuffer() を使用します。
実装例:
16バイトの ArrayBuffer を作成します。
// ArrayBuffer を作成
const myBuf = new ArrayBuffer(16);
// バイト単位の長さを取得
let len = myBuf.byteLength;- ArrayBuffer のサイズはバイト(Bytes)単位で指定します。
- byteLength プロパティがそのサイズを表します。
- 一度作成されると、サイズを変更することはできません。
3. ArrayBuffer へのアクセス
ArrayBuffer 自体には、データを「読み取る(Read)」または「書き込む(Write)」ためのメソッドは存在しません。
データにアクセスするには、必ずビュー(View)を使用する必要があります。
型付き配列(Typed Arrays)や DataView は、ArrayBuffer に対して数値データを読み書きする手段を提供します。
一般的な型付き配列:
- Uint8Array - 8ビット符号なし整数
- Int16Array - 16ビット符号付き整数
- Int32Array - 32ビット符号付き整数
- Float32Array - 32ビット浮動小数点数
- Float64Array - 64ビット浮動小数点数
4. Uint8Array の使用例
各 Uint8 は 1 バイトを使用します。
実装例:
// 8バイトの ArrayBuffer を作成
const myBuf = new ArrayBuffer(8);
// Uint8Array ビューを作成
const view = new Uint8Array(myBuf);
// 最大 8 つの値を書き込む
view[0] = 10;
view[2] = 128;
view[1] = 255;
// 値を読み取る
let v0 = view[0];
let v1 = view[1];
let v2 = view[2];5. Int32Array の使用例
各 Int32 は 4 バイトを使用します。
実装例:
// 12バイトの ArrayBuffer を作成
const myBuf = new ArrayBuffer(12);
// Int32Array ビューを作成
const view = new Int32Array(myBuf);
// 12バイト = 最大 3 つの Int32 値を格納可能
view[0] = 100000;
view[1] = 200000;
view[2] = 300000;
// 値を読み取る
let v0 = view[0];
let v1 = view[1];
let v2 = view[2];6. DataView の使用
DataView は、ArrayBuffer のためのより柔軟なビューです。
DataView を使用すると、異なる型(Int8, Uint16, Float32 など)の値を混在させて読み書きでき、任意のバイトオフセットで操作が可能です。
実装例:DataView による読み書き
// 8バイトの ArrayBuffer を作成
const myBuf = new ArrayBuffer(8);
// DataView を作成
const view = new DataView(myBuf);
// バイトオフセット 0 に 32ビット整数を書き込む
view.setInt32(0, 123456);
// バイトオフセット 4 に 16ビット整数を書き込む
view.setInt16(4, 32000);
// 値を読み取る
let v1 = view.getInt32(0);
let v2 = view.getInt16(4);補足: DataView の各メソッドには、バイトオーダー(エンディアン)を制御するためのオプション引数 littleEndian (true/false) が存在します。7. ArrayBuffer のスライス(Slicing)
slice() メソッドを使用すると、ArrayBuffer の一部のコピーを作成できます。指定された範囲のバイトを含む新しい ArrayBuffer が返されます。
実装例:ArrayBuffer.slice()
// 8バイトの ArrayBuffer を作成
const myBuf = new ArrayBuffer(8);
// Uint8Array を作成
const view = new Uint8Array(myBuf);
// 0 から 7 までの値を設定
for (let i = 0; i < view.length; i++) {
view[i] = i;
}
// 2バイト目から 5バイト目(5は含まない)までのコピーを作成
const sliced = myBuf.slice(2, 5);
const slicedView = new Uint8Array(sliced);slice()メソッドは新しいバッファを作成します。- コピーされたバッファは、元のバッファとメモリを共有しません。
8. 文字列の変換
8.1 文字列から ArrayBuffer への変換 (UTF-8)
function stringToArrayBuffer(str) {
const encoder = new TextEncoder();
return encoder.encode(str).buffer;
}
const myBuf = stringToArrayBuffer("Hello");
let len1 = myBuf.byteLength;8.2 ArrayBuffer から 文字列への変換 (UTF-8)
function arrayBufferToString(buffer) {
const decoder = new TextDecoder();
return decoder.decode(new Uint8Array(buffer));
}
const encoder = new TextEncoder();
const myBuf = encoder.encode("Hello ArrayBuffer").buffer;
let text = arrayBufferToString(myBuf);9. ArrayBuffer の共有 (SharedArrayBuffer)
標準的な ArrayBuffer は、デフォルトではスレッド(メインスレッドと Web Workers など)間で共有されません。
ワーカー間でメモリを共有するために、JavaScript は SharedArrayBuffer を提供しています。
これは ArrayBuffer と同様に動作しますが、その内容は共有可能であり、Atomics オブジェクトと組み合わせて使用されます。
実装例:SharedArrayBuffer の作成
let buffer;
// セキュリティ要件を満たしているか確認
if (Window.crossOriginIsolated) {
buffer = new SharedArrayBuffer(16);
} else {
buffer = new ArrayBuffer(16);
}
const sharedView = new Int32Array(buffer);
// 値の設定
sharedView[0] = 42;
let numb = sharedView[0];重要: ブラウザで SharedArrayBuffer を有効にするには、特定のセキュリティヘッダー(COOP/COEP)の設定が必要になる場合があります。
10. まとめ
- ArrayBuffer は固定サイズのメモリブロックを表す低レベルオブジェクトです。
- ArrayBuffer に直接読み書きすることはできず、必ずビュー(型付き配列または DataView)を介してアクセスします。
- 型付き配列は一律の数値データに適しており、DataView は混合データや構造化されたデータに適しています。
- バッファの一部をコピーするには
slice()を使用します。 - 共有メモリによる並行処理には SharedArrayBuffer と Atomics を使用します。