JavaScript の「型付き配列(Typed Arrays)」を初心者向けにやさしく詳しく説明します。
ざっくり言うと:Typed Arrays は「生のバイナリ(メモリ上の生データ)」を扱うための、配列っぽい仕組みです。音声・画像・ネットワークの生データや、WebAssembly とやり取りするときに使います。普通の Array と似ている部分もありますが、役割と使い方がかなり違います。
基本の考え方(バッファとビュー)
Typed Arrays は「バッファ(ArrayBuffer / SharedArrayBuffer)」と「ビュー(TypedArray / DataView)」の2つに分かれます。
- バッファ(ArrayBuffer)
メモリ上の「ただの箱(連続したバイト列)」です。要素の型や並び方は何も決まっていません。作るときはバイト数で指定します。直接値を読み書きすることはできません。 - ビュー(TypedArray / DataView)
バッファの中身を「どんな型で」「どこから」「何個分」読むかを決める窓です。たとえばUint8Arrayは 1 バイト単位の「符号なし8ビット整数」の窓、Float32Arrayは 4 バイトごとに「32ビット浮動小数点数」として見る窓です。DataViewはさらに低レベルで、バイト単位で細かく操作できます。
図でイメージすると:大きな箱(バッファ)があって、そこに複数の「窓(ビュー)」を取り付けて、窓ごとに違う解釈で中身を見る、という感じです。
よく使う型(代表例)
主要な TypedArray の種類と、1要素あたりのバイト数の例:
Int8Array(1バイト、-128~127)Uint8Array(1バイト、0~255)Uint8ClampedArray(0〜255 に自動制限、画像処理で便利)Int16Array(2バイト)Int32Array/Uint32Array(4バイト)Float32Array(4バイト、単精度)Float64Array(8バイト、倍精度)BigInt64Array/BigUint64Array(8バイト、BigInt 用)
具体的な使い方(コード例)
読みやすいように段階的に示します(ブラウザのコンソールや Node.js で動きます)。
1) ArrayBuffer を作る(バイト数を指定)
// 8バイトのバッファを作成
const buffer = new ArrayBuffer(8);
console.log(buffer.byteLength); // 8
JavaScript2) 同じバッファを違うビューで見る
const u8 = new Uint8Array(buffer); // 1バイト単位で見る
const f64 = new Float64Array(buffer); // 8バイト(1個分)を float64 として見る
u8[0] = 1;
u8[1] = 2;
console.log(u8); // Uint8Array(8) [...]
console.log(f64[0]); // バイト列を float64 として解釈した値(意味のある数とは限らない)
JavaScript→ 同じバッファを Uint8Array と Float64Array が別々に「違う見方」で読んでいる点に注目してください。MDNウェブドキュメント
3) 型付き配列を直接作る(要素数を指定)
const arr = new Int16Array(4); // Int16(2バイト)を4要素分作る(合計8バイト)
arr[0] = 1000;
console.log(arr[0]); // 1000
JavaScript4) ArrayBuffer とオフセットを使う(部分だけを見る)
const main = new ArrayBuffer(16);
const viewA = new Uint8Array(main, 0, 8); // 先頭8バイト
const viewB = new Uint16Array(main, 8, 4); // 9バイト目から 16バイト目までを 2バイト単位で
JavaScript5) DataView を使ってエンディアンを指定して読み書き
DataView はバイトオーダー(リトル / ビッグエンディアン)を明示できるので、ネットワークやファイルフォーマットの解析で重宝します。
const buf = new ArrayBuffer(4);
const dv = new DataView(buf);
dv.setUint16(0, 0x1234, true); // リトルエンディアンで書く
console.log(dv.getUint16(0, true)); // 0x1234
JavaScript※ TypedArray はエンディアンを意識せず高速に連続データを扱うのに向いており、DataView は個別の位置で細かく扱いたいときに使います。
何が普通の配列と違うの?
- 型が固定:
Int16Arrayなら各要素は常に 16 ビット整数です(自動で変換されます)。普通のArrayはどんな型も混在できます。 - メモリ上で連続:TypedArray はメモリ上に連続して配置されるので、高速にアクセスできます(ネイティブに近い性能)。
- サイズが固定:作った長さを簡単に増やせません(
Arrayのようにpush()は基本的に使えない)。 - Array.isArray() は false:見た目は配列っぽくても、
Array.isArray()はfalseを返します。
どんなときに使うのが良い?
- 画像データ(Canvas のピクセルバッファ)を直接操作するとき。(
Uint8ClampedArray)。 - WebSocket や Fetch の
arrayBuffer()で得たバイナリを解析するとき。 - WebAudio や音声データ、ビデオフレームの処理。
- WebAssembly とメモリを共有してやり取りするとき。
- バイナリファイル(独自フォーマット)を読んで値を取り出すとき(DataView が特に便利)。
よくある間違いと注意点
- **エンディアン(バイト順)**の扱い:ネットワークやファイルによってバイト順が決まっている場合があり、DataView で正しく扱わないと数字が逆になります。
- **共有メモリ(SharedArrayBuffer)**はスレッド間で同時アクセスが可能で、競合を起こすため
Atomicsを使う必要がある場合があります。 - サイズ変更:普通の TypedArray は長さ変更できない(新しく作り直すかバッファを slice する)。ただし
ArrayBuffer側にresize()などの新しい API もあります(対応状況に注意)。
まとめ(初心者向け一言)
- Typed Arrays は「メモリ上の生データを型付きで高速に扱う道具」です。
- 「箱(ArrayBuffer)」を作って、「窓(TypedArray / DataView)」で中を見るイメージ。
- 音声・画像・ネットワーク・WebAssembly 等、バイナリを直接扱う場面で役立ちます。
