MENU

JavaScript配列・連想配列関数・メソッドArrayBuffer

【JavaScript】 ArrayBufferとTypedArray-メモリを確保してアクセス

更新日:2021/07/06

 

プログラムコードを組んでいると、任意サイズのメモリを確保して、バイナリデータバッファなどの利用目的で自由にアクセスしたいことがあります。

 

JavaScriptでは、ArrayBufferオブジェクトとTypedArrayオブジェクトを使用することで実現できますが、初見では少し仕組みが分かりにくく感じます。

 

そこでまずは、概要として二つのオブジェクトの関係と、それぞれの使用方法をお伝えします。

 

概要

 

概要と言っても、それほど難しくはありません。

 

メモリ確保とアクセスに関するオブジェクトの関係を図に示すと次のようになります。

 

ArrayBuffer/TypedArray/DataViewの関係

 

 

メモリ確保を行うオブジェクト - ArrayBufferオブジェクト -

 

メモリ確保とアクセスの仕組みで中心的な役割を果たすのが、ArrayBufferオブジェクトです。
ArrayBufferオブジェクトはメモリの確保をおこない、内部プロパティ(JavaScriptコードから参照できないプロパティ)に割り当てます。

 

ArrayBufferオブジェクトはメモリの確保をしますが、確保したメモリにアクセスする機能は用意されていません。

 

ArrayBufferオブジェクト

 

 

アクセスはインターフェースとして用意されたオブジェクト(DataViewオブジェクトTypedArrayオブジェクト)を経由しておこないます。

 

 

インターフェース1 - DataViewオブジェクト -

 

DataViewオブジェクトは、ArrayBufferオブジェクトで確保したメモリの任意位置へのデータ書き込み、および読み込みができます。

 

データの形式(8ビット型・符号なし8ビット型・16ビット整数型など)毎に書き込み・読み込みのメソッドが用意されています。

 

DataViewオブジェクト

 

実際には、ArrayBufferオブジェクトの内部プロパティからメモリの実体を取得し、DataViewオブジェクトのメソッドがメモリに直接アクセスしています。

 

 

インターフェース2 - TypedArrayオブジェクト -

 

実際にはTypedArrayというオブジェクトは存在しません。
TypedArrayは、下表のオブジェクトの総称です。

 

オブジェクト名バイト数範囲
Int8Array18ビット2の補数符号付き整数-128~127
Uint8Array18ビット符号なし整数0~255
Uint8ClampedArray18ビット符号なし整数(クランプ変換0~255
Int16Array216ビット2の補数符号付き整数-32768~32767
Uint16Array216ビット符号なし整数0~65535
Int32Array432ビット2の補数符号付き整数-2147483648~
2147483647
Uint32Array432ビット符号なし整数0~4294967295
BigInt64Array864ビット2の補数符号付き整数-9223372036854775808~
9223372036854775807
BigUint64Array864ビット符号なし整数0~18446744073709551615
Float32Array432ビットIEEE浮動小数点
Float64Array864ビットIEEE浮動小数点

 

これらのオブジェクトをArrayBufferオブジェクトで確保したメモリへのインターフェースとすることで、各型の配列としてアクセスできるようになります。

 

また、forEachやindexOfなどのArrayオブジェクトが持っているメソッドと同じ名前のメソッドを使用することができます。

 

TypedArrayオブジェクト

 

Uint8ClampedArrayに値をセットするとき、値が255を超えている場合255がセットされます。
値が整数でないときは四捨六入されますが、小数が.5のとき偶数値が選択されます。
例:[3.5 → 4] [4.5 → 4]

 

ArrayBufferオブジェクトの共有

 

複数のインターフェースで、一つのArrayBufferオブジェクトを共有することもできます。

 

ArrayBufferオブジェクトの共有

 

それぞれのインターフェースは、独立して動作します。

 

例えばInt16Arrayで2バイトの値をセットしたあとに、同じ位置にInt8Arrayで1バイトをセットしようとした場合、元からある値を考慮せずに上書きされます。

 

ArrayBufferオブジェクトを共有したインターフェース間の書き込み

使用方法

 

DataViewオブジェクトと、TypedArrayオブジェクトの使用方法を簡単に説明します。

 

 

DataViewオブジェクトの使用方法

 

 

インスタンス作成

 

DataViewオブジェクトは、ArrayBufferオブジェクトを引数としてインスタンスを作成します。

 

インスタンス作成

 


const dataView = new DataView( new ArrayBuffer(4) );

 

バッファの一部だけをDataViewオブジェクトに割り当てることもできます。

 

バッファの一部だけを割り当ててインスタンス作成

 


const arrayBuf = new  ArrayBuffer(4);
const dataView = new DataView(  arrayBuf , 1 , 2 );

console.log( dataView.byteOffset , dataView.byteLength );  // 1 2

 

DataViewコンストラクターの2番目の引数が開始バイト位置(0から)、3番目の引数が割り当てるバイト数です。

 

上の例では位置1から2バイト分をDataViewオブジェクトに割り当てています。

 

DataView 一部のみ割り当て

 

割り当て開始位置はbyteOffsetプロパティで、割り当てたバイト数はbyteLengthプロパティで確認できます。

 

また、第一引数で指定したArrayBufferオブジェクトを、bufferプロパティで確認できます。

 

割り当てたメモリは、割り当て開始位置をインデックス0としてアクセスできます。

 

内部的な処理では、インデックスでアクセスする都度、割り当てられたArrayBufferオブジェクト(ここではarrayBuf)と、割り当て開始位置、割り当てたバイト数を元に、アクセス位置が計算されます。

 

 

ArrayBuffer共有

 

ArrayBufferオブジェクトを共有する場合はDataViewオブジェクトのbufferプロパティを使用するか、ArrayBufferオブジェクトを変数にセットしておき、再利用します。

 

 

ArrayBufferを共有するインスタンス作成

 


const dataView = new DataView( new ArrayBuffer(4) );

const dataView2 = new DataView( dataView.buffer );

 

または

 


const aryBuffer = new ArrayBuffer(4);
const dataView = new DataView( aryBuffer );

const dataView2 = new DataView( aryBuffer );

 

 

また、バッファーの一部を共有することもできます。

 

ArrayBufferの一部を共有するインスタンス作成

 


   // 先頭から2バイトを割り当て
const dataView = new DataView( new ArrayBuffer(4) , 0 , 2 );

   // 位置2から2バイトを割り当て
const dataView2 = new DataView( dataView.buffer , 2 , 2 );

   // バッファー全体を割り当て
const dataView3 = new DataView( dataView2.buffer );

  // bufferプロパティは同じオブジェクトを返す
console.log( dataView2.buffer === dataView.buffer );   // true

 

 

bufferプロパティは、共有されている範囲ではなく、第一引数で指定したArrayBufferオブジェクトを返します。
そのため上の例のように、ArrayBufferオブジェクトを変数に格納する必要がありません。

 

バッファの一部を共有する場合は、第二引数に0から始まる共有開始位置を、第三引数に共有するバイト数を指定します。

 

次のように、バッファー外の数値を指定するとエラーになります。

 

バッファー外の数値を指定するとエラー

 


const dataView = new DataView( new ArrayBuffer(4) , 0 , 5 );
 // Uncaught RangeError: invalid data view length

 


const dataView = new DataView( new ArrayBuffer(4) , 5 , 5 );
 // Uncaught RangeError: start offset is outside the bounds of the buffer

 

データの取得/セット

 

データの取得およびセットは、専用のメソッドを使用します。

 

データの取得およびセット

 


const dataView = new DataView( new ArrayBuffer(4) );

dataView.setUint16( 0 , 0x1a1b); // 符号なし2バイト整数を0バイト目にセット
dataView.setUint16( 2 , 0x1c1d); // 符号なし2バイト整数を2バイト目にセット

const byteString = [];

  // 1バイトずつ取得
for( let i = 0 ; i < dataView.byteLength ; i ++ )
    byteString.push( 
        dataView.getUint8( i ).toString(16) // 1バイト取得後16進文字列に変換
    );

console.log( byteString.join( " " ) ); // 1a 1b 1c 1d

 

バッファーサイズは、byteLengthプロパティで取得します。
lengthプロパティではないので、注意が必要です。

 

TypedArrayオブジェクトの使用方法

 

 

インスタンス作成

 

TypedArrayオブジェクトはDataViewオブジェクトと同じように、ArrayBufferオブジェクトを引数としてインスタンス作成できます。

 

インスタンス作成

 


const u8 = new Uint8Array( new ArrayBuffer(4) );

 

ただし入力されるバッファーは、TypedArrayオブジェクトのバイト数の倍数である必要があります。

 

例えば、Uint16Arrayのバイト数が2バイトなので、バッファーサイズは2の倍数バイトが要求されます。
つまり、次のように奇数を指定するとエラーになります。

 

バッファーサイズが正しくない

 


const u16 = new Uint16Array( new ArrayBuffer(5)  );
 // Uncaught RangeError: attempting to construct out-of-bounds TypedArray on ArrayBuffer

 

TypedArrayオブジェクトには、ArrayBufferオブジェクトを引数とする方法以外にもインスタンス作成手段が用意されています。

 

以降の方法は、インスタンス作成時にArrayBufferオブジェクトが作成されます。
作成されたArrayBufferオブジェクトはTypedArrayオブジェクトにリンクされます。

 

いくつかの方法があります。

 

要素数を指定して作成

 

コンストラクターの引数に整数値を指定すると、その値とTypedArrayオブジェクトのバイト数を掛けたバイト数分のバッファーが確保されます。

 

要素数を指定してインスタンス作成

 


    // 8ビット(1バイト)符号なし整数を10個確保
const u8 = new Uint8Array( 10 ); 
    // 16ビット(2バイト)符号なし整数を10個確保
const u16 = new Uint16Array( 10 );

console.log( u8.length , u8.byteLength );    // 10 10
console.log( u16.length , u16.byteLength );  // 10 20

 

lengthプロパティは要素数(インデックスの数)で、byteLengthはバッファーメモリのバイト数です。

 

Uint8Arrayは、1要素1バイトのため、lengthbyteLengthが同じ値になります。

 

一方、Uint16Arrayは1要素2バイトなので、byteLengthlength × 2 という計算で求めることができます。

 

 

値を指定して作成

 

格納する値を指定して、バッファーを確保することも可能です。
方法としてはいくつかあります。

 

配列で指定

 


const u8 = new Uint8Array( [ 1001 ,1002 , 1003 ] );
console.log( u8 );  //  [ 233, 234, 235 ]

 

TypedArrayで指定

 


const u16 = new Uint16Array( [ 1001 ,1002 , 1003 ] );

const u8 = new Uint8Array( u16 );
console.log( u8 ); // [ 233, 234, 235 ]

 

TypedArrayは疑似的な配列とみなすことができるので、『配列で指定』『TypedArrayで指定』は、実質的に同じです。

 

配列の要素は、TypedArrayオブジェクトの型に変換されます。
そのため上の例では、引数で指定した値と異なる値でUint8Arrayオブジェクトが生成されています。

 

『TypedArrayで指定』のコードは、バッファ共有と混同しやすいので注意が必要です。
上の例では、変数u16が持つバッファーから、u8のバッファーへ値が2バイトから1バイトへ変換しながらコピーされています。

 

値コピーと共有コードを並べてみたので、どこが違うのか確認してみてください。

 

値をコピー:const u8 = new Uint8Array( u16 );
バッファを共有:const u8 = new Uint8Array( u16.buffer );

 

 

値を指定してバッファーを作成する方法は、まだあります。

 

引数の羅列で指定

 


const u8 = Uint8Array.of( 1001 ,1002 , 1003 );
console.log( u8 ); // [ 233, 234, 235 ]

 

TypedArrayのofメソッドを使用すると、引数の羅列で値を指定できます。
引数は、TypedArrayオブジェクトの型に変換されます。

 

コンストラクターでの初期化ではなく、メソッド呼び出しなのでnewは必要ありません。

 

コールバックで指定

 


const u8a = Uint8Array.from( [1001 ,1002 , 1003] ,  v => v * 2 );
console.log( u8a );  // [ 210, 212, 214 ]

const u8b = Uint8Array.from( [1001 ,1002 , 1003] ,
            function(v) { return v * this.n } ,
            { n : 2 } 
        );
console.log( u8b );  // [ 210, 212, 214 ]

const u8c = Uint8Array.from({ length:3 } ,
            function(v,index) { return this.v[index] * this.n } ,
             { n : 2 , v:[ 1001 ,1002 , 1003]} 
        );
console.log( u8c );  // [ 210, 212, 214 ]

 

 

こちらもコンストラクターではなくて、TypedArrayのメソッド呼び出しです。

 

TypedArrayのfromメソッドを使用すると、配列の要素を元にコールバックで値を指定できます。

 

このメソッドは、Array.fromと同じ動作をおこないます。
ただし、格納される値がTypedArrayの型に変換される点が異なります。

 

Array.fromについては、次の記事を読んでみてください。
【JavaScript】 Array.fromの使い方を理解する

 

ArrayBuffer共有

 

ArrayBuffer共有は、DataViewオブジェクトと同じ方法でおこないます。

 

ArrayBufferを共有するインスタンス作成

 


const u8 = new Uint8Array( 4 );
const u16 = new Uint16Array( u8.buffer );

 

または

 


const aryBuffer = new ArrayBuffer(4);
const u8 = new Uint8Array( aryBuffer );
const u16 = new Uint16Array( aryBuffer );

 

 

バッファーの一部を共有することもできます。

 

ArrayBufferの一部を共有するインスタンス作成

 


   // 先頭から2バイトを割り当て
const u8 = new Uint8Array( new ArrayBuffer(8) , 0 , 2 );

   // 位置2から1要素(2バイト)を割り当て
const u16 = new Uint16Array( u8.buffer , 2 , 1 );

   // 位置4から1要素(4バイト)を割り当て
const u32 = new Uint32Array( u16.buffer , 4 , 1);

  // bufferプロパティは同じオブジェクトを返す
console.log( u16.buffer === u32.buffer );   // true

 

 

bufferプロパティは、共有されている範囲ではなく、第一引数で指定したArrayBufferオブジェクトを返します。

 

バッファの一部を共有する場合は、第二引数に0から始まる共有開始位置をバイト数で、第三引数に共有する要素数を指定します。

 

開始位置は、TypedArrayオブジェクトのバイト数の倍数である必要があります。

 

例:
Uint8Array 0 , 1 , 2 , 3 , ・・・
Uint16Array 0 , 2 , 4 , 6 , ・・・
Uint32Array 0 , 4 , 8 , 12 , ・・・

 

次のコードはエラーになります。

 

位置が不正のためエラー

 


const u32 = new Uint32Array( new ArrayBuffer(8) , 3 , 1);
 // Uncaught RangeError: attempting to construct out-of-bounds TypedArray on ArrayBuffer

 

また、第三引数はバイト数でなく要素数であることに注意してください。

 

次のコードは、共有範囲がバッファーの外に出てしまったのでエラーになります。

 

共有範囲外のためエラー

 


const u32 = new Uint32Array( new ArrayBuffer(8) , 4 , 2);
 // Uncaught RangeError: attempting to construct out-of-bounds TypedArray on ArrayBuffer

 

データの取得/セット

 

TypedArrayの値取得およびセットは、配列形式でおこないます。

 

データの取得/セット

 


const u16 = new Uint16Array( new ArrayBuffer(4));

u16[0] = 10000000;
u16[1] = u16[0] + 40000000;

u16.forEach( (e,index)=>console.log( index , e) ); 
  // 0 38528
  // 1 61568

 

なお、値はセット時に各TypedArrayの型に変換されます。
そのため上のコードは、セットした値と異なる値が取得されています。

 

 

 

ArrayBufferオブジェクトデータの外部保存/読み込み

 

ArrayBufferオブジェクトで管理しているメモリを外部ファイルに保存したり、外部ファイルをメモリに保存するケースがあります。

 

ここではその方法について概略を、ブラウザ版とNode.js版についてお伝えします。

 

ブラウザでの保存/読み込み

 

 

読み込み

 

ブラウザで外部ファイルを取り扱う場合、ブラウザに組み込まれているFile APIを使用します。

 

File APIは次のようなhtmlを記述することで、ファイル選択インターフェースを表示することができます。

 

<input type="file">

 

File API

 

ここでファイルが選択されると、changeイベントが発行されます。

 

通常は読み込みボタンなどを設置すべきですが、今回はchangeイベントで読み込んでみます。

 

コード

 

HTML

 


<input type="file" id="fileinput">

<div id="result"></div>

 

 

JavaScript

 


window.addEventListener( "DOMContentLoaded" , ()=> {

    const fileInput = document.getElementById("fileinput");
    const result = document.getElementById("result");

    const fileLoad = file => {
        const reader = new FileReader();
        reader.onload = ()=> {
            const u8 = new Uint8Array(reader.result);
            const length = Math.min( u8.length , 100 );
            const resultBuff = [];

            for( let i = 0 ; i < length ; i ++ )
                resultBuff.push( `${i} ${ u8[i].toString( 16 ) }`);
            result.innerHTML = resultBuff.join("<br>");
        };
        reader.onerror = () => {
            reader.abort();
            alert(`${file.name}を読み込めませんでした`);
        };
        reader.readAsArrayBuffer(file);
    };

    fileInput.addEventListener("change", e => fileLoad(fileInput.files[0]));
});

 

概要

 

changeイベント発生時、fileLoad関数の引数として fileInput.files[0] を指定しています。
fileInput.filesには現在指定されているファイルの情報が格納されています。
今回は1ファイルのみなのでゼロ番目を渡しています。

 

fileLoad関数では、最初にFileReaderオブジェクトを作成しています。
このオブジェクトとFile APIから受け取ったファイル情報を使用すると、外部ファイルを読み込むことができます。

 

その前に、FileReaderオブジェクトのonプロパティをセットします。
これは、ファイルが正常に読み込まれたときに呼び出されるコールバック関数です。

 

onerrorプロパティは、読み込みが失敗したときに呼び出されるコールバック関数です。

 

最後に readAsArrayBuffer メソッドにとFile APIから受け取ったファイル情報を引数として渡して実行すると、読み込みが始まります。

 

このメソッドは名前からわかるように、読み込んだデータをArrayBufferとして受け取ることができます。
この時点で、ArrayBufferへの読み込みは完了したようなものです。

 

読み込みが完了すると、onloadプロパティにセットした関数が呼び出されます。
このとき、FileReaderオブジェクトのresultプロパティには、ArrayBufferがセットされています。

 

そこで、バイト単位でアクセスできるようにUint8Arrayを用意しています。
あとは最大100バイトまで、一つずつブラウザに表示しています。

 

 

保存

 

ブラウザでの保存は、イメージ的にはファイルのダウンロードです。

 

ArrayBufferのデータをダウンロードできる形式に変換します。

 

次に内部でリンクタグ(aタグ)を用意して、hrefと変換したデータを関連付けます。

 

最後に、内部でリンクタグをクリックします。

 

HTML

 


<button id="download">ダウンロード</button>

 

 

JavaScript

 


window.addEventListener( "DOMContentLoaded" , ()=> {

const download = document.getElementById("download");
    
    const fileDownload = (filename,data) => {
        const blob = new Blob([data], {type: "octet/stream"});
        const url = URL.createObjectURL(blob);
    
        const aTag = document.createElement("a");
        aTag.href = url;
        aTag.target = "_blank";
        aTag.download = filename;
        aTag.click();
        URL.revokeObjectURL(url);
    };
    
    const FILE_NAME = "download.dat";
    const data = Uint8Array.of( 10 , 20 , 30 , 40 , 50 );
    
    download.addEventListener("click", e => fileDownload( FILE_NAME,data.buffer ));
});

 

 

 

Node.jsでの保存/読み込み

 

Node.jsでの保存と読み込みは、次の記事で紹介しています。
そちらをご覧ください。

 

 

DataViewオブジェクトのプロパティ・メソッド

 

new等で作成したDataViewインスタンスには、次のプロパティおよびメソッドがあります。

 

プロパティ

 

DataViewインスタンスは、関連付けられているArrayBufferの情報を取得するプロパティが用意されています。

 

プロパティ名内容
bufferDataViewオブジェクトに関連付けられているArrayBufferを返す
byteOffsetDataViewオブジェクトに関連付けられているArrayBufferの参照開始位置
byteLengthDataViewオブジェクトに関連付けられているArrayBufferの参照バイト数

 

使用例

 


const arrayBuffer = new ArrayBuffer(10);

const dataView1 =  new DataView( arrayBuffer );

console.log( arrayBuffer === dataView1.buffer ); // true
console.log( dataView1.byteOffset ); // 0
console.log( dataView1.byteLength ); // 10

const dataView2 =  new DataView( dataView1.buffer , 2 , 4 );
console.log( dataView2.byteOffset ); // 2
console.log( dataView2.byteLength ); // 4

 

メソッド

 

DataViewインスタンスは、様々な形式でArrayBufferに値をセットしたり取得するためのメソッドが用意されています。

 

get系メソッド

 

get系メソッドは、関連付けられているArrayBufferからメソッド毎に決められたバイト数を取り出し、各形式に変換した値を返します。

 

2バイト以上のメソッドは、エンディアンを指定することができます。

 

エンディアンについてはこちらをご覧ください

エンディアンとは何か調べてみた

 

メソッド名引数バイト数内容
getInt8書き込むバイト位置18ビット2の補数符号付き整数を取得
getUint818ビット符号なし整数を取得
getInt16

第一引数:書き込むバイト位置
第二引数:リトルエンディアンフラグ(真偽値)

 

※第二引数について

省略可能です
true:リトルエンディアンが選択されます
false:ビッグエンディアンが選択されます(規定値)

216ビット2の補数符号付き整数を取得
getUint16216ビット符号なし整数を取得
getInt32432ビット2の補数符号付き整数を取得
getUint32432ビット符号なし整数を取得
getBigInt64864ビット2の補数符号付き整数を取得
getBigUint64864ビット符号なし整数を取得
getFloat32432ビットIEEE浮動小数点を取得
getFloat64864ビットIEEE浮動小数点を取得

 

set系メソッド

 

set系メソッドは、値を各形式に変換した後バイト単に組み替え、関連付けられているArrayBufferに格納します。

 

2バイト以上のメソッドは、エンディアンを指定することができます。

 

エンディアンについてはこちらをご覧ください

エンディアンとは何か調べてみた

 

メソッド名引数バイト数内容
setInt8第一引数:バイト位置
第二引数:書き込む値
18ビット2の補数符号付き整数をセット
setUint818ビット符号なし整数をセット
setInt16

第一引数:バイト位置
第二引数:書き込む値
第三引数:リトルエンディアンフラグ(真偽値)

 

※第三引数について

省略可能です
true:リトルエンディアンが選択されます
false:ビッグエンディアンが選択されます(規定値)

216ビット2の補数符号付き整数をセット
setUint16216ビット符号なし整数をセット
setInt32432ビット2の補数符号付き整数をセット
setUint32432ビット符号なし整数をセット
setBigInt64864ビット2の補数符号付き整数をセット
setBigUint64864ビット符号なし整数をセット
setFloat32432ビットIEEE浮動小数点をセット
setFloat64864ビットIEEE浮動小数点をセット

 

使用例

 


const dataView =  new DataView( new ArrayBuffer(10) );

    // ビッグエンディアンで書き込み
dataView.setUint16( 0 , 0x1234 );

   // ビッグエンディアンで取得
console.log( dataView.getUint16( 0  ).toString(16) ); // 1234
   // リトルエンディアンで取得
console.log( dataView.getUint16( 0 ,true ).toString(16) ); // 3412

    // リトルエンディアンで書き込み
dataView.setUint16( 2 , 0x1234 , true );

   // ビッグエンディアンで取得
console.log( dataView.getUint16( 2  ).toString(16) ); // 3412
   // リトルエンディアンで取得
console.log( dataView.getUint16( 2 ,true ).toString(16) ); // 1234

TypedArrayオブジェクトのプロパティ・メソッド

 

インスタンスのプロパティ・メソッド

 

new等で作成したTypedArrayインスタンスには、次のプロパティおよびメソッドがあります。

 

プロパティ

 

TypedArrayオブジェクトには、関連付けられているArrayBufferの情報を取得するプロパティが用意されています。

 

プロパティ名内容
bufferTypedArrayオブジェクトに関連付けられているArrayBufferを返す
byteOffsetTypedArrayオブジェクトに関連付けられているArrayBufferの参照開始位置
byteLengthTypedArrayオブジェクトに関連付けられているArrayBufferの参照バイト数
lengthTypedArrayオブジェクト上での要素数
BYTES_PER_ELEMENT一要素当たりのバイト数

 

使用例

 


const u16 =  new Uint16Array( 5 );

console.log( u16.byteOffset ); // 0
console.log( u16.byteLength ); // 10
console.log( u16.length ); // 5

const u16_2 =  new Uint16Array( u16.buffer , 2 , 2 );
console.log( u16_2.byteOffset ); // 2
console.log( u16_2.byteLength ); // 4
console.log( u16_2.length );  // 2

 

メソッド

 

TypedArrayオブジェクトは、Arrayオブジェクトと同名のメソッドが用意されています。
※全て同じというわけではありません。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

メソッド名引数([]は省略可)内容使用例
copyWithintarget, start [ , end ]
返り値:this値

ArrayBufferの位置startから
位置endの直前までを
ArrayBufferの位置targetにコピー
const u16 = Uint16Array.of( 0 , 0 , 0x1234 , 0x5678 );

console.log( u16.copyWithin( 0 , 2 ) );
// int16Array(4) [ 4660, 22136, 4660, 22136 ]

entriesなし
返り値:イテレーター
配列[インデックス,値]を返す、
イテレーターを返す
const u16 = Uint16Array.of( 0x1234 , 0x5678 , 0x9ABC );

for( const e of u16.entries() )
console.log( `key:${e[0]} value:${e[1].toString(16)}` );
// key:0 value:1234,key:1 value:5678,key:2 value:9abc

everycallbackfn [ , thisArg ]
返り値:真偽値
関数callbackfnによる
値チェック。
全てtrueのとき
結果がtrueとなる
const u16 = Uint16Array.of( 0 , 0 , 0 , 0 );

console.log( u16.every( e=>e>0) ); // true
console.log( u16.every( e=>e!==3) ); // false

filtercallbackfn [ , thisArg ]
返り値:新しいTypedArray
関数callbackfnによる
値チェック。
trueの要素で
新規のArrayBuffer
およびTypedArrayを作成
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.filter( e=>e>2 ) );
// key:0 value:3 , key:1 value:4

findcallbackfn [ , thisArg ]
返り値:要素の値
関数callbackfnによる
値チェック。
最初のtrueの要素を返す
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.find( e=>e>2) ); // 3

findIndexcallbackfn [ , thisArg ]
返り値:インデックス
関数callbackfnによる
値チェック。
最初のtrueの要素の
インデックスを返す
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.findIndex( e=>e>2) ); // 2

forEachcallbackfn [ , thisArg ]
返り値:undefined
関数callbackfnによる
値処理
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

u16.forEach( e=>console.log(e) );
// 1 , 2 , 3 , 4

includessearchElement [ , fromIndex ]
返り値:真偽値
searchElementが含まれているか
どうかのチェック
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.includes( 3 ) ); // true

indexOfsearchElement [ , fromIndex ]
返り値:インデックス
searchElementと一致する
要素のインデックスを返す
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.indexOf( 3 ) ); // 2

joinseparator
返り値:文字列
各要素を10進数
文字列化し
separatorで連結します
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.join( "," ) ); // 1,2,3,4
参考:【JavaScript】 数値配列を16進数でjoinする

keysなし
返り値:イテレーター
インデックスを順番に返す
イテレーターを返します
const u16 = Uint16Array.of( 0x1234 , 0x5678 , 0x9ABC );

for( const e of u16.keys() )
console.log( `key:${e}` );
// key:0 key:1 key: 2 key:3

lastIndexOfsearchElement [ , fromIndex ]
返り値:インデックス
searchElementと一致する
最後の要素のインデックスを返す
const u16 = Uint16Array.of( 1 , 3 , 3 , 4 );

onsole.log( u16.lastIndexOf(3)); // 2

mapcallbackfn [ , thisArg ]
返り値:新しいTypedArray
各要素を関数callbackfn
に渡した結果から、
新しいTypedArrayおよび
ArrayBufferを作成する
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.map(e=>e*2) );
// Uint16Array(4) [ 2, 4, 6, 8 ]

reducecallbackfn [ , thisArg ]
返り値:処理結果
各要素を順番に処理して
結果を得る
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.reduce( (a,b)=>a+b , 0 ) );
// 10

reverseなし
返り値:this値
要素の位置を反転させるconst u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.reverse( ) );
// Uint16Array(4) [ 4, 3, 2, 1 ]

setarrayOrtypedArray [ , offset ]
返り値:undefined
arrayOrtypedArray
(アレイライクまたは
TypedArray)から、
要素をコピーする
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

u16.set( {length:2,0:5,1:7} );
console.log( u16 );
// Uint16Array(4) [ 1, 5, 7, 4 ]

slicestart, end
返り値:新しいTypedArray
位置startから位置end
の直前までを新しいTypedArrayと
ArrayBufferにコピーする
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.slice( 1,3 ) );
// Uint16Array(2) [ 2, 3 ]

somecallbackfn [ , thisArg ]
返り値:真偽値
関数callbackfnによる
値チェック。
一つでもtrueのとき
結果がtrueとなる
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 );

console.log( u16.some( e=>e===3) ); // true
console.log( u16.some( e=>e===5) ); // false

sortcomparefn
返り値:真偽値
関数comparefnにより
要素を並び変える
const u16 = Uint16Array.of( 2 , 6 , 1 , 8 );

console.log( u16.sort( (a,b)=>b-a) ); // [ 8, 6, 2, 1 ]

subarraybegin, end
返り値:新しいTypedArray
同じArrayBufferを参照する
TypedArrayを作成します。
TypedArray上の位置beginから
位置endの直前までを
範囲とします。
const u16 = Uint16Array.of( 1 , 2 , 3 , 4 , 5 , 6 );

const u16sub = u16.subarray( 2 ,6 ); // [ 3 , 4 , 5 , 6 ]
const u16sub2 = u16sub.subarray( 2 ,6 ); // [ 5 , 6 ]
console.log( u16.buffer === u16sub.buffer ); // true

toLocaleString[ reserved1 [ , reserved2 ] ]
返り値:文字列
言語に合わせた形式で文字列化するconst u16 = Uint16Array.of( 1 , 2 , 3 , 4 , 5 , 6 );

console.log( u16.toLocaleString() ); // 1,2,3,4,5,6

toString
返り値:文字列
文字列化するconst u16 = Uint16Array.of( 1 , 2 , 3 , 4 , 5 , 6 );

console.log( u16.toString() ); // 1,2,3,4,5,6

valuesなし
返り値:イテレーター
値を順番に返す
イテレーターを返します
const u16 = Uint16Array.of( 0x1234 , 0x5678 , 0x9ABC );

for( const e of u16.values() )
console.log( `value:${e.toString(16)}` );
// value:1234 value:5678 value:9abc

 

TypedArrayコンストラクタのプロパティ・メソッド

 

インスタンスではなく、TypedArrayコンストラクタから直接呼び出すプロパティおよびメソッドには、次のようなものがあります。

 

プロパティ

 

プロパティ名内容
BYTES_PER_ELEMENT一要素当たりのバイト数

 

メソッド

 

メソッド名引数([]は省略可)内容使用例
fromsource [ , mapfn [ , thisArg ] ]
返り値:TypedArray
アレイライクオブジェクトsource
コールバック関数mapfnからインスタンスを作成
こちらを参照
of...items
返り値:TypedArray
引数の羅列からインスタンスを作成こちらを参照

けーちゃんおススメJavaScript入門書

  • スラスラ読める JavaScript ふりがなプログラミング
  • プログラム未経験者がJavaScript始めるならコレ!
    コードを掲載して自分で理解しろという投げっぱなしな入門書とは異なり、コードに一つ一つどんなことをやっているかをふりがなという形式で解説しています。
    それでいてJavaScriptの基礎と応用を学べる良書です。
  • これからWebをはじめる人のHTML&CSS、JavaScriptのきほんのきほん
  • JavaScriptの機能を実践で活かすにはHTMLやCSSの知識が不可欠です。
    しかしそれらの知識があることが前提として書かれている書籍が多い中、この本は総合的な知識を身に着けることができます。
    HTMLやCSSの知識も不安な方には、ぴったりの一冊です
  •  

    入門書の役割は、自分のやりたいことをネットで調べることができるようになるための、基礎的な知識の獲得です。
    まずはこれらの本でしっかりと基礎知識を身につけましょう。
    そしてもっと高度なことや専門的なことはネットで調べ、情報が足りないと感じたら書籍を購入してください。


    期間限定情報:
    7/16から7/18は63時間のビッグセール!
    欲しかったアレが安く手に入るチャンスです
    忘れずにチェックしてください!
    僕は以前のタイムセール祭りで4Kモニタが買ったけど、それより安かったらどうしよう・・・

    さらにお得なポイントアップキャンペーンも同時開催!

    記事の内容について

     

    こんにちはけーちゃんです。
    説明するのって難しいですね。


    「なんか言ってることおかしくない?」
    たぶん、こんなご意見あると思います。

    裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。

    そんなときは、ご意見もらえたら嬉しいです。

    ご意見はこちら。
    https://note.affi-sapo-sv.com/info.php

    【お願い】

    お願い

    ■このページのURL


    ■このページのタイトル


    ■リンクタグ


    ※リンクして頂いた方でご希望者には貴サイトの紹介記事を作成してリンクを設置します。
    サイト上部の問い合わせよりご連絡ください。
    ただしサイトのジャンルによっては、お断りさせていただくことがあります。