JavaScript DataView: 初心者向けガイド

こんにちは、未来のJavaScript魔法使いさんたち!今日は、DataViewオブジェクトの世界に興味深い旅に出発します。 előtte még soha nem hallottál róluk? - このチュートリアルの終わりまでに、バイナリデータをプロのように扱うことができるようになるでしょう!

JavaScript - DataView

DataViewとは?

本格的な内容に入る前に、基本から始めましょう。あなたは一名の探偵で、不思議なパッケージが満ちたバイナリデータを受け取ったとします。それを理解するにはどうすればいいのでしょうか?それがDataViewが助け舟を貸すところです!

DataViewオブジェクトは、ArrayBuffer内の複数の数値型を読み書きすることができ、コンピュータのエンディアンに関係なく動作します(後で説明します)。まるでバイナリデータの万能翻訳者を持っているようなものです!

シntax

まず、DataViewオブジェクトをどのように作成するか見てみましょう:

new DataView(buffer [, byteOffset [, byteLength]])

これを見て驚かないでください!見たよりもシンプルです。以下に分解します:

  • buffer:私たちのバイナリデータのコンテナであるArrayBufferです。
  • byteOffset(省略可能):バッファから読み始める場所。
  • byteLength(省略可能):ビューに含めるバイト数。

例:DataViewオブジェクトの作成

手をこまねいて、最初のDataViewオブジェクトを作成しましょう:

// まず、16バイトのArrayBufferを作成します
const buffer = new ArrayBuffer(16);

// それで、バッファ全体をカバーするDataViewを作成します
const view1 = new DataView(buffer);

// そして、バイト12から始まり、4バイトの長さのDataViewを作成します
const view2 = new DataView(buffer, 12, 4);

console.log(view1.byteLength); // 出力:16
console.log(view2.byteLength); // 出力:4

この例では、まず16バイトのArrayBufferを作成します。これを16ピクセルの空白キャンバスと考えてください。次に、以下のDataViewオブジェクトを作成します:

  1. view1はバッファ全体をカバーします。
  2. view2はバイト12から始まり、最後の4バイトをカバーします。

これがまるでデータを見るための二つの拡大鏡を持っているようなものです!

JavaScript DataViewプロパティ

DataViewには便利なプロパティがあります。見てみましょう:

プロパティ 説明
buffer DataViewが参照しているArrayBufferを返します
byteLength DataViewの長さ(バイト単位)を返します
byteOffset DataViewのオフセット(バイト単位)をArrayBufferの開始位置からのものとして返します

以下にこれらのプロパティの使用方法を示します:

const buffer = new ArrayBuffer(16);
const view = new DataView(buffer, 2, 12);

console.log(view.buffer);       // ArrayBuffer(16)
console.log(view.byteLength);   // 12
console.log(view.byteOffset);   // 2

この例では、バッファのバイト2から始まり、12バイトの長さを持つDataViewを作成します。プロパティを使ってこれらの詳細を確認します。

JavaScript DataViewメソッド

さあ、エキサイティングな部分に進みましょう - メソッドです!DataViewは、異なる数値型を読み書きするためのメソッドを提供します。以下に最もよく使われるメソッドの一覧を示します:

メソッド 説明
getInt8(byteOffset) 指定されたバイトオフセット位置の符号付き8ビット整数を取得します
getUint8(byteOffset) 指定されたバイトオフセット位置の無符号8ビット整数を取得します
getInt16(byteOffset [, littleEndian]) 指定されたバイトオフセット位置の符号付き16ビット整数を取得します
getUint16(byteOffset [, littleEndian]) 指定されたバイトオフセット位置の無符号16ビット整数を取得します
getInt32(byteOffset [, littleEndian]) 指定されたバイトオフセット位置の符号付き32ビット整数を取得します
getUint32(byteOffset [, littleEndian]) 指定されたバイトオフセット位置の無符号32ビット整数を取得します
getFloat32(byteOffset [, littleEndian]) 指定されたバイトオフセット位置の32ビット浮動小数点数を取得します
getFloat64(byteOffset [, littleEndian]) 指定されたバイトオフセット位置の64ビット浮動小数点数を取得します

これらのgetメソッドに対応するsetメソッドもあります。

以下にいくつかのメソッドの使用例を見てみましょう:

const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);

// データを書き込みます
view.setInt16(0, 42);
view.setFloat32(2, 3.14);

// そして、データを読み取ります
console.log(view.getInt16(0));   // 出力:42
console.log(view.getFloat32(2)); // 出力:3.140000104904175

この例では、バイトオフセット0に16ビット整数(42)を書き込み、バイトオフセット2に32ビット浮動小数点数(3.14)を書き込みます。次に、これらの値を読み取ります。浮動小数点数の値が正確に3.14でないことに注意してください - これはバイナリで浮動小数点数が保存される方法によるものです。

エンディアンの謎

先ほどエンディアンについて言及しましたが、その謎を解き明かす時がきました!エンディアンとは、バイトがより大きな数値に並べられる順序のことを指します。以下の二種類があります:

  1. リトルエンディアン:最も小さなバイトが最初に来ます。
  2. ビッグエンディアン:最も大きなバイトが最初に来ます。

これを数え字に例えると、123はビッグエンディアン(最も大きな数字が最初)、321はリトルエンディアン(最も小さな数字が最初)です。

DataViewの素晴らしいところは、マルチバイト値を読み書きする際にエンディアンを指定できることです。以下に例を示します:

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);

view.setUint16(0, 0x1234, true);  // リトルエンディアン
view.setUint16(2, 0x5678, false); // ビッグエンディアン

console.log(view.getUint16(0, true));  // 0x1234
console.log(view.getUint16(0, false)); // 0x3412
console.log(view.getUint16(2, true));  // 0x7856
console.log(view.getUint16(2, false)); // 0x5678

この例では、同じ値を異なるエンディアンで書き込み、その後異なるエンディアンで読み取ります。まるで本を左から右へ、そして右から左へ読むようなものです!

結論

おめでとうございます!あなたはDataViewの世界への最初の一歩を踏み出しました。私たちはDataViewオブジェクトの作成、プロパティの使用、そしてメソッドを用いたデータ操作について説明しました。エンディアンの謎も解き明かしました!

バイナリデータとの作業は最初は難しいように思えるかもしれませんが、DataViewを使えば強力なツールを手に入れることができます。まるでバイナリデータのスイスアーミーナイフのように、多様で正確で非常に有用です。

JavaScriptの旅を続ける中で、ファイルフォーマットやネットワークプロトコルなどの複雑なバイナリデータ構造を扱う際にDataViewが非常に価値のあるものになることを発見するでしょう。練習を続けて、すぐにあなたも真のコードの探偵のようにビットとバイトを操ることができるようになるでしょう!

Credits: Image by storyset