この節では、インデックス値により順序付けされたデータのコレクションを紹介します。配列、 Array オブジェクト、 TypedArray オブジェクトなどの配列用の構造体があります。

Array オブジェクト

配列は名前やインデックスで参照できる値からなる順序付け集合です。例えば、 emp という配列を作成し、数値の従業員番号から従業員の名前を引けるようにすることができます。つまり、 emp[1] が従業員番号 1 、 emp[2] が従業員番号 2 、のようになります。

JavaScript は明確な配列データ型を持っていません。しかし、アプリケーションで配列として機能する定義済みの Array オブジェクトとそのメソッドを利用できます。 Array オブジェクトには配列の結合、反転、ソートなど様々な方法で配列を操作するメソッドがあります。また、配列の長さを特定するプロパティや、正規表現で使用するプロパティなどがあります。

配列の生成

以下の文は同じ配列を生成します。

var arr = new Array(element0, element1, ..., elementN);
var arr = Array(element0, element1, ..., elementN);
var arr = [element0, element1, ..., elementN];

element0, element1, ..., elementN は配列要素となる値から構成されるリストです。これらの値が指定されると、この配列の要素はそれらの値に初期化されます。配列の length プロパティは引数の数に設定されます。

角括弧による構文は「配列リテラル」または「配列初期化子」と呼ばれます。この構文はその他の形式による配列作成よりも短いため、一般的に好まれる方法です。詳細については、配列リテラルをご覧ください。

長さがゼロではないが項目のない配列を作成するには、以下の方法が使用できます。

var arr = new Array(arrayLength);
var arr = Array(arrayLength);

// この方法はちょうど同じ結果になります
var arr = [];
arr.length = arrayLength;

注: 上記のコードでは、 arrayLengthNumber(数値)である必要があります。さもないと、(指定した値の)単一の要素を持つ配列が生成されます。arr.length を呼び出すと arrayLength が返されますが、実際には配列は空要素 (undefined) で構成されます。この配列で for...in ループを実行しても、配列の要素は返されません。

上記のように新規に定義した変数に割り当てるだけでなく、新規または既存のオブジェクトのプロパティに配列を割り当てることができます。

var obj = {};
// ...
obj.prop = [element0, element1, ..., elementN];

// あるいは、
var obj = {prop: [element0, element1, ...., elementN]};

単一の要素で配列を初期化しようとして、その要素が Number である場合、角括弧の構文を使用する必要があります。単一の Number 値が Array() コンストラクタや関数に渡されると、単一の数値要素としてではなく、arrayLength として解釈されます。

var arr = [42];      // 42という数の要素を
                     // 1個だけ持つ配列が作られる。

var arr = Array(42); // 要素がなく、arr.length が
                     // 42に設定された配列が作られる。
                     // 以下のコードと同様。
var arr = [];
arr.length = 42;

N の値が小数部分がゼロではない実数である場合、Array(N) を呼び出すと、結果は RangeError になります。以下の例ではこの動作を示します。

var arr = Array(9.3);  // RangeError: Invalid array length

任意のデータ型の単一の要素を持つ配列を作成したければ、配列リテラルを使用する方が安全です。あるいは、単一の要素を追加する前に空の配列を作成しましょう。

ES2015 から単一の要素を持つ配列を生成するために Array.of 静的メソッドを使用することができます。

let wisenArray = Array.of(9.3);  // よく考えられ、たった1つの要素 9.3 だけを持つ配列

 

 

配列へのデータ追加

要素に値を割り当てることで配列にデータを追加することができます。例えば、

var emp = [];
emp[0] = 'Casey Jones';
emp[1] = 'Phil Lesh';
emp[2] = 'August West';

注: 上記のコードで配列演算子(角括弧)内に非整数値を指定すると、配列要素ではなく配列を表すオブジェクト内のプロパティとして作成されます。

var arr = [];
arr[3.4] = 'Oranges';
console.log(arr.length);                // 0
console.log(arr.hasOwnProperty(3.4));   // true

配列を作成するときにも、データを追加することができます。

var myArray = new Array('Hello', myVar, 3.14159);
var myArray = ['Mango', 'Apple', 'Orange'];

配列要素の参照

要素に付けられた序数を使って配列要素を参照することができます。例えば、次のような配列を定義しましょう。

var myArray = ['Wind', 'Rain', 'Fire'];

配列の最初の要素は myArray[0] として参照し、二番目の要素は myArray[1] として参照します。要素のインデックスはゼロから始まります。

注 : 配列演算子(角括弧)は配列のプロパティにアクセスする際にも使用できます(つまり JavaScript では配列はオブジェクトでもあります)。以下の例をご覧ください。

var arr = ['one', 'two', 'three'];
arr[2];  // three
arr['length'];  // 3

配列の長さの理解

実装レベルでは、 JavaScript の配列はその添字をプロパティ名として使うことで、実際には標準のオブジェクトプロパティとして要素を格納しています。しかし length プロパティは特別です。これは常に最終要素の添字+1を返します(次の例では、 Dusty の添字は30なので、 cats.length は30+1を返します)。JavaScript の配列の添字は 0 オリジン (0-based) です。1からではなく、0から始まります。つまり、 length プロパティは配列に格納されている最大の添字より1多い値になるということです :

var cats = [];
cats[30] = ['Dusty'];
console.log(cats.length); // 31

length プロパティに値を割り当てることもできます。格納されているアイテムの数より小さい値を設定すると、配列は切り捨てられます。すなわち、0に設定すると完全に配列を空にします。

var cats = ['Dusty', 'Misty', 'Twiggy'];
console.log(cats.length); // 3

cats.length = 2;
console.log(cats); // "Dusty, Misty" がログ出力される - Twiggy は削除される

cats.length = 0;
console.log(cats); // ログは出力されない、配列 cats は空になる

cats.length = 3;
console.log(cats); // [undefined, undefined, undefined]

配列の反復処理

よく行われるのは配列の値に対する反復処理ですが、それぞれの値に対して処理を行う方法がいくつかあります。これを行う一番簡単な方法は次のとおりです。

var colors = ['red', 'green', 'blue'];
for (var i = 0; i < colors.length; i++) {
  console.log(colors[i]);
}

配列内の要素がいずれも真偽値としては false に評価されないことがわかっている場合 ― 例えば配列が DOM ノードのみで構成されている場合などには、例のように、より効率的なイディオムを使用できます。

var divs = document.getElementsByTagName('div');
for (var i = 0, div; div = divs[i]; i++) {
  /* div に対して何らか処理をする */
}

この例では、配列の長さのチェックに掛かるオーバーヘッドを回避しています。そしてより便利に使えるように、ループの反復のたびに div 変数に現在の項目を代入するようにしています。

配列を反復処理する別の方法として forEach() メソッドがあります。

var colors = ['red', 'green', 'blue'];
colors.forEach(function(color) {
  console.log(color);
});
// red
// green
// blue

他に、ES2015 のアロー関数を forEach の引数にしてコードを短くすることができます。

var colors = ['red', 'green', 'blue'];
colors.forEach(color => console.log(color)); 
// red
// green
// blue

forEach に渡される関数では、その関数への引数に配列の要素が渡されて、配列内の各項目ごとに1回ずつ実行されます。値が割り当てられていない要素は forEach ループで反復されません。

配列定義の際に省略された要素は、 forEach によって反復処理されるときには現れませんが、配列要素に undefined が割り当てられている場合は現れることに注意してください。

var array = ['first', 'second', , 'fourth'];

array.forEach(function(element) {
  console.log(element);
});
// first
// second
// fourth

if (array[2] === undefined) { 
  console.log('array[2] is undefined'); // true
} 

array = ['first', 'second', undefined, 'fourth'];

array.forEach(function(element) {
  console.log(element);
});
// first
// second
// undefined
// fourth

JavaScript では、配列の要素は標準的なオブジェクトプロパティとして保存されるので、 for...in ループを使って JavaScript 配列を反復処理するのはお勧めできません。というのも、通常の要素とすべての列挙可能なプロパティが現れるからです。

配列のメソッド

Array オブジェクトには以下のようなメソッドがあります。

concat() は2つの配列を結合し、新しい配列を返します。

var myArray = new Array('1', '2', '3');
myArray = myArray.concat('a', 'b', 'c'); 
// myArray は ["1", "2", "3", "a", "b", "c"] になる

join(delimiter = ',') は配列のすべての要素を文字列に結合します。

var myArray = new Array('Wind', 'Rain', 'Fire');
var list = myArray.join(' - '); // list は "Wind - Rain - Fire" になる

push() は1つ以上の要素を配列の最後に追加し、その新しい配列の長さを返します。

var myArray = new Array('1', '2');
myArray.push('3'); // myArray は ["1", "2", "3"] になる

pop() は配列から最後の要素を取り除き、その要素を返します。

var myArray = new Array('1', '2', '3');
var last = myArray.pop(); 
// myArray は ["1", "2"] に、 last は "3" となる

shift() は配列から最初の要素を取り除き、その要素を返します。

var myArray = new Array('1', '2', '3');
var first = myArray.shift(); 
// myArray は ["2", "3"]に、first は "1" になる

unshift() は1つ以上の要素を配列の先頭に追加し、その新しい配列の長さを返します。

var myArray = new Array('1', '2', '3');
myArray.unshift('4', '5'); 
// myArray は ["4", "5", "1", "2", "3"] となる

slice(start_index, upto_index) は配列の一部を抽出し、新しい配列を返します。

var myArray = new Array('a', 'b', 'c', 'd', 'e');
myArray = myArray.slice(1, 4); // 添字1から始め、添字3まですべての要素を
                               // 展開して、[ "b", "c", "d"] を返す

splice(index, count_to_remove, addElement1, addElement2, ...) は要素を配列から取り除き、(必要に応じて)置き換えます。

var myArray = new Array('1', '2', '3', '4', '5');
myArray.splice(1, 3, 'a', 'b', 'c', 'd'); 
// myArray は ["1", "a", "b", "c", "d", "5"] となる
// このコードでは添字1の要素("2"がある場所)から始め、
// 3つの要素を削除して、その場所に連続した要素
// すべてを挿入する

reverse() は配列の中の要素をその場で反転させます。配列の最初の要素が最後に、最後の要素が最初になります。配列への参照を返します。

var myArray = new Array('1', '2', '3');
myArray.reverse(); 
// 配列要素が入れ替えられ、myArray = ["3", "2", "1"] となる

sort() は配列の要素をその場でソートし、その配列の参照を返します。

var myArray = new Array('Wind', 'Rain', 'Fire');
myArray.sort(); 
// 配列がソートされ、myArray = ["Fire", "Rain", "Wind"] となる

sort() は要素を比較する方法を特定するために、コールバック関数を取ることがあります。

sort メソッドを始めとする以下のメソッドは 反復メソッド (iterative method) と呼ばれ、何らかの形で配列全体を反復処理します。それぞれが任意で thisObject と呼ばれる第二引数を受け取ります。 thisObject が与えられた場合、これがコールバック関数の本体内で this キーワードの値になります。与えられなかった場合は、関数が明示的なオブジェクトコンテキストの外で呼び出された場合と同様に、 はグローバルオブジェクト(window)を参照します。

コールバック関数は配列の要素である、2つの引数で呼び出されます。

以下の関数は2つの値を比較して、3つの値のうち1つを返します。

つまり、以下の例は文字列の最後の文字で並べ替えをします。

var sortFn = function(a, b) {
  if (a[a.length - 1] < b[b.length - 1]) return -1;
  if (a[a.length - 1] > b[b.length - 1]) return 1;
  if (a[a.length - 1] == b[b.length - 1]) return 0;
}
myArray.sort(sortFn); 
// 配列がソートされ、 myArray = ["Wind","Fire","Rain"] となる
  • このソートシステムにより ab より小さいとされた場合、-1(または、任意の負の数)を返します。
  • このソートシステムにより ab より大きいとされた場合、1(または、任意の正の数)を返します。
  • ab が等値と見なされる場合、0を返します。

indexOf(searchElement[, fromIndex]) は配列から searchElement を検索します。そして、最初にマッチした位置の添字を返します。

var a = ['a', 'b', 'a', 'b', 'a'];
console.log(a.indexOf('b')); // 1がログ出力される
// 最後にマッチした位置の後から検索を再開する
console.log(a.indexOf('b', 2)); // 3がログ出力される
console.log(a.indexOf('z')); // 'z'は見つからないので-1がログ出力される

lastIndexOf(searchElement[, fromIndex])indexOf のように動作します。しかし、最後の要素から開始して後方に検索します。

var a = ['a', 'b', 'c', 'd', 'a', 'b'];
console.log(a.lastIndexOf('b')); // 5 がログ出力される
// 最後にマッチした位置の前から検索を再開する
console.log(a.lastIndexOf('b', 4)); // 1 がログ出力される
console.log(a.lastIndexOf('z')); // -1 がログ出力される

forEach(callback[, thisObject]) はすべての配列アイテムにコールバック関数 callback を実行し、 undefined を返します。

var a = ['a', 'b', 'c'];
a.forEach(function(element) { console.log(element); }); 
// 順番にそれぞれのアイテムをログ出力する

map(callback[, thisObject]) はすべての配列アイテムごとにコールバック関数 callback を実行し、戻り値からなる新しい配列を返します。

var a1 = ['a', 'b', 'c'];
var a2 = a1.map(function(item) { return item.toUpperCase(); });
console.log(a2); // A,B,C がログ出力される

filter(callback[, thisObject]) はコールバック関数 callback が true を返すアイテムからなる新しい配列を返します。

var a1 = ['a', 10, 'b', 20, 'c', 30];
var a2 = a1.filter(function(item) { return typeof item === 'number'; });
console.log(a2); // logs [10, 20, 30]

every(callback[, thisObject]) はコールバック関数 callback が配列内のすべてのアイテムで true を返す場合に true を返します。

function isNumber(value) {
  return typeof value === 'number';
}
var a1 = [1, 2, 3];
console.log(a1.every(isNumber)); // logs true
var a2 = [1, '2', 3];
console.log(a2.every(isNumber)); // logs false

some(callback[, thisObject]) はコールバック関数 callback が配列内の少なくとも一つのアイテムで true を返す場合に true を返します。

function isNumber(value) {
  return typeof value === 'number';
}
var a1 = [1, 2, 3];
console.log(a1.some(isNumber)); // logs true
var a2 = [1, '2', 3];
console.log(a2.some(isNumber)); // logs true
var a3 = ['1', '2', '3'];
console.log(a3.some(isNumber)); // logs false

reduce(callback[, initialValue]) はアイテムリストを単一の値に還元し、それを返す callback(firstValue, secondValue) を適用します。

var a = [10, 20, 30];
var total = a.reduce(function(first, second) { return first + second; }, 0);
console.log(total) // 60 が出力される

reduceRight(callback[, initialValue])reduce() のように機能します。しかし最後の要素から適用を開始します。

reducereduceRight もある意味では配列の反復メソッドです。数列を単一の値に還元する際、再帰的に2つの値を組み合わせるアルゴリズムにこれらのメソッドを使用してください。

多次元配列

配列をネストすることができます、つまり配列要素として配列を含めることができることを意味します。JavaScript の配列の特徴を活かして、多次元配列を生成できます。

以下のコードでは2次元配列を作成しています。

var a = new Array(4);
for (i = 0; i < 4; i++) {
  a[i] = new Array(4);
  for (j = 0; j < 4; j++) {
    a[i][j] = '[' + i + ', ' + j + ']';
  }
}

この例では、次のテーブル行を持つ配列を作成しています。

Row 0: [0, 0] [0, 1] [0, 2] [0, 3]
Row 1: [1, 0] [1, 1] [1, 2] [1, 3]
Row 2: [2, 0] [2, 1] [2, 2] [2, 3]
Row 3: [3, 0] [3, 1] [3, 2] [3, 3]

配列と正規表現

配列が正規表現と文字列との間のマッチ結果である場合、その配列はマッチについての情報を提供するプロパティと要素を返します。RegExp.exec()String.match()String.split() による戻り値がこうした配列となります。正規表現とともに配列を使用する際の情報については、当ガイドの正規表現の章をご覧ください。

配列様のオブジェクトを利用する

document.getElementsByTagName() によって返される NodeList や、関数本体内で利用できる arguments オブジェクトのように、表面上は配列のようにふるまう JavaScript オブジェクトがありますが、これらは関数メソッドすべてを共有してはいません。例えば、arguments オブジェクトには length 属性がありますが、forEach() メソッドは実装されていません。

その他の配列様オブジェクトとは対照的に、Array プロトタイプメソッドは呼び出しが可能です。例えば、

function printArguments() {
  Array.prototype.forEach.call(arguments, function(item) {
    console.log(item);
  });
}

その上 Array プロトタイプメソッドは文字列上で利用できるので、配列と同じ方法でこれらの文字に順次アクセスできます。

Array.prototype.forEach.call('a string', function(chr) {
  console.log(chr);
});

型付き配列

JavaScript の型付き配列は配列様のオブジェクトで、未加工のバイナリデータにアクセスする仕組みをもたらします。ご存知のように、 Array オブジェクトは動的に拡大、縮小し、JavaScript におけるいかなる値でも保持することができます。JavaScript エンジンは最適化を行うため、これらの配列は高速に機能します。しかし、オーディオやビデオ操作といった機能が追加され、WebSocket を使い未加工のデータにアクセスするなど、Webアプリケーションはさらにパワフルなものとなってきました、そのため JavaScript コードが型付き配列内の未加工バイナリデータを手早く簡単に操作できれば有益である場合がよくある、ということが明らかになってきました。

バッファとビュー : 型付き配列のアーキテクチャ

最大の柔軟性と効率性を達成するため、JavaScript 型付き配列の実装をバッファビューに分離しました。バッファ(ArrayBuffer オブジェクトによる実装)はデータのかたまりを表すオブジェクトです。対話を行うためのフォーマットではなく、データの中身にアクセスするためのメカニズムを提供しません。バッファに含まれる記録にアクセスするには、ビューを使用する必要があります。ビューは実際の型付き配列からデータを送信するコンテキスト — つまり、データ型、オフセットの開始位置、要素数 — を提供します。

Typed arrays in an ArrayBuffer

ArrayBuffer

ArrayBuffer は汎用的な固定長のバイナリデータバッファを表すために使用されるデータ型です。ArrayBuffer の内容は直接操作できません。かわりに、型付き配列ビューか特定のフォーマットでバッファを表す {jsxref("DataView")}} を生成し、それらをバッファの内容の読み書きに使用します。

型付き配列ビュー

型付き配列ビューは自己記述的な名前を持っていて、そのすべてが Int8, Uint32, Float64 などといったよく見られる数値型用のビューを提供しています。Uint8ClampedArray という1つ特別な型付き配列ビューがあります。これは、0〜255 の範囲に値を固定します。これは、例えば、Canvas のデータ処理に便利です。

値の範囲 サイズ (バイト数) 説明 Web IDL 型 同等の C 型
Int8Array -128 から 127 1 8 ビット長、2 の補数方式の符号付き整数値 byte int8_t
Uint8Array 0 から 255 1 8 ビット長、符号なし整数値 octet uint8_t
Uint8ClampedArray 0 から 255 1 8 ビット長、符号なし整数値 (切り詰め) octet uint8_t
Int16Array -32768 から 32767 2 16 ビット長、2 の補数方式の符号付き整数値 short int16_t
Uint16Array 0 から 65535 2 16 ビット長、符号なし整数値 unsigned short uint16_t
Int32Array -2147483648 から 2147483647 4 32 ビット長、2 の補数方式の符号付き整数値 long int32_t
Uint32Array 0 から 4294967295 4 32 ビット長、符号なし整数値 unsigned long uint32_t
Float32Array 1.2x10-38 から 3.4x1038 4 32 ビット長、IEEE 方式 浮動小数点数 unrestricted float float
Float64Array 5.0x10-324 から 1.8x10308 8 64 ビット長、IEEE 方式 浮動小数点数 unrestricted double double

詳細については、JavaScript 型付き配列と様々な TypedArray オブジェクトに関するリファレンスをご覧ください。

ドキュメントのタグと貢献者

このページの貢献者: kenji-yamasaki, mfuji09, YuichiKamiki, x2357, shide55
最終更新者: kenji-yamasaki,