JavaScript アドバンス

JavaScript 型付き配列

1. Typed Arrays(型付き配列)とは?

Typed Arrays(型付き配列)は、バイナリデータを扱うために設計されました。 通常の配列とは異なり、型付き配列は固定長(Fixed Length)のバッファです。 また、8ビット整数や32ビット浮動小数点数といった固定されたデータ型(Fixed Types)の要素を格納します。

1.1 作成例

5バイトの型付き配列を作成:

const myArr = new Uint8Array(5);

配列から型付き配列を作成:

const myArr = new Uint8Array([0,1,2,3,4]);

数値のリストから型付き配列を作成:

const myArr = Uint8Array.of(0,1,2,3,4);

配列(Iterable)から型付き配列を作成:

const myArr = Uint8Array.from([0,1,2,3,4]);

2. Typed Array のメリット

Typed Arrays は、バイナリデータを効率的に扱う方法を提供するために設計されました。これは、複数のデータ型が混在できる従来の JavaScript 配列とは対照的です。

型付き配列は生のメモリ(Raw Memory)であるため、JavaScript はデータを別の表現に変換することなく、そのまま任意の関数に渡すことができます。
生のバイナリデータを利用できる関数にデータを渡す際、型付き配列は通常の配列よりも遥かに高速です。主に以下の用途に適しています:

  • WebGL と Canvas: 高速なグラフィックスレンダリングや画像処理。
  • File API: ローカルファイルの高速な読み書き。
  • Media API: オーディオやビデオデータの高速なハンドリング。
  • WebSockets: ネットワーク経由の効率的なバイナリデータ転送。

型付き配列は、C言語の配列と同じくらい効率的にバイナリデータを扱う手段を提供します。

3. Typed Arrays をサポートするブラウザ API

3.1 Fetch API の例

fetch(url)
.then(request => request.arrayBuffer())
.then(arrayBuffer => {
  // バイナリデータとして処理
});

3.2 Canvas の例

const canvas = document.getElementById('my_canvas');
const context = canvas.getContext('2d');
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
// imageData.data は Uint8ClampedArray を返す
const uint8ClampedArray = imageData.data;

4. 通常の配列との違い

  • 固定長(Fixed Length): push()pop() メソッドを使用して動的にサイズを変更することはできません。
  • 型の制約(Type Restriction): 要素は、その型付き配列で指定されたデータ型に従う必要があります。
  • 基盤となるバッファ(Underlying Buffer): 型付き配列は ArrayBuffer に対する「ビュー(View)」であり、バイナリデータの直接操作を可能にします。

5. 型付き配列の種類(Typed Array Types)

名前最小値最大値バイト数
Int8Array-1281271 byte8ビット符号付き整数
Uint8Array02551 byte8ビット符号なし整数(オクテット)
Uint8ClampedArray02551 byte8ビット符号なし整数(クランプ処理あり)
Int16Array-32768327672 bytes16ビット符号付き整数
Uint16Array0655352 bytes16ビット符号なし整数
Int32Array-214748364821474836474 bytes32ビット符号付き整数
Uint32Array042949672954 bytes32ビット符号なし整数
BigInt64Array-2⁶³2⁶³ - 18 bytes64ビット符号付き整数
BigUint64Array02⁶⁴ - 18 bytes64ビット符号なし整数
Float16Array-65504655042 bytes16ビット半精度浮動小数点数
Float32Array-3.4e383.4e384 bytes32ビット単精度浮動小数点数
Float64Array-1.8e3081.8e3088 bytes64ビット倍精度浮動小数点数

6. 8ビット整数(8-Bit Integers)

名前データ型範囲
Int8Array符号付き整数 (byte)-128 / 127
Uint8Array符号なし整数 (octet)0 / 255
Uint8ClampedArray符号なし整数 (clamped)0 / 255

6.1 実装例

10個の符号付き8ビット整数の型付き配列を作成:

const myArr = new Int8Array(10);

10個の符号なし8ビット整数の型付き配列を作成:

const myArr = new Uint8Array(10);

10個の符号なし8ビット整数(クランプ形式)の型付き配列を作成:

const myArr = new Uint8ClampedArray(10);

6.2 Uint8Array vs Uint8ClampedArray

Uint8ArrayUint8ClampedArray の違いは、値が範囲外になった際の処理方法にあります。
Uint8ClampedArray で 0〜255 の範囲外の値を設定しようとすると、自動的に 0 または 255 に固定(クランプ)されます。一方で、通常の Uint8Array は、単純に値の最初の8ビットだけを取得します。

注意: 型付き配列は厳密には「配列(Array)」ではありません。型付き配列に対して Array.isArray() を実行すると false が返されます。また、pushpop のような多くの配列メソッドはサポートされていません。

7. 16ビット整数(16-Bit Integers)

名前データ型範囲
Int16Array短精度整数 (short)-32768 / 32767
Uint16Array符号なし短精度整数0 / 65535

7.1 実装例

// 10個の符号付き16ビット整数の型付き配列
const myArr = new Int16Array(10);

// 10個の符号なし16ビット整数の型付き配列
const myArr = new Uint16Array(10);

8. 32ビット整数(32-Bit Integers)

名前データ型範囲
Int32Array符号付き長精度整数 (long)-2147483648 / 2147483647
Uint32Array符号なし長精度整数0 / 4294967295

8.1 実装例

// 10個の符号付き32ビット整数の型付き配列
const myArr = new Int32Array(10);

// 10個の符号なし32ビット整数の型付き配列
const myArr = new Uint32Array(10);

9. 64ビット整数(64-Bit Integers)

名前データ型範囲
BigInt64Array巨大な符号付き整数-2⁶³ / 2⁶³ - 1
BigUint64Array巨大な符号なし整数0 / 2⁶⁴

9.1 実装例

// 10個の符号付き64ビット整数(bigint形式)の型付き配列
const myArr = new BigInt64Array(10);

// 10個の符号なし64ビット整数(bigint形式)の型付き配列
const myArr = new BigUint64Array(10);

10. 浮動小数点数

名前説明範囲
Float16Array半精度 - 有効桁数約3桁-65504 / 65504
Float32Array単精度 - 有効桁数約7桁-3.4e38 / 3.4e38
Float64Array倍精度 - 有効桁数約15桁-1.8e308 / 1.8e308

ECMAScript 標準で規定されている通り、JavaScript における通常の算術演算は「倍精度浮動小数点数(double-precision floating-point arithmetic)」を使用して行われます。

10.1 実装例

// 10個の16ビット半精度浮動小数点数の型付き配列
const myArr = new Float16Array(10);

// 10個の32ビット単精度浮動小数点数の型付き配列
const myArr = new Float32Array(10);

// 10個の64ビット倍精度浮動小数点数の型付き配列
const myArr = new Float64Array(10);