JavaScript | 第15章「JavaScript の型付き配列」

javascrpit JavaScript
スポンサーリンク

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
JavaScript

2) 同じバッファを違うビューで見る

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

→ 同じバッファを Uint8ArrayFloat64Array が別々に「違う見方」で読んでいる点に注目してください。MDNウェブドキュメント

3) 型付き配列を直接作る(要素数を指定)

const arr = new Int16Array(4); // Int16(2バイト)を4要素分作る(合計8バイト)
arr[0] = 1000;
console.log(arr[0]); // 1000
JavaScript

4) ArrayBuffer とオフセットを使う(部分だけを見る)

const main = new ArrayBuffer(16);
const viewA = new Uint8Array(main, 0, 8);  // 先頭8バイト
const viewB = new Uint16Array(main, 8, 4); // 9バイト目から 16バイト目までを 2バイト単位で
JavaScript

5) 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 等、バイナリを直接扱う場面で役立ちます。
タイトルとURLをコピーしました