JavaScript の Array
オブジェクトは、配列を構築するためのグローバルオブジェクトです。配列とは、高レベルのリスト構造のようなオブジェクトです。
配列を作成する
var fruits = ["りんご", "バナナ"]; console.log(fruits.length); // 2
配列の要素を取得する
var fruits = ["りんご", "バナナ"]; var first = fruits[0]; // りんご var last = fruits[fruits.length - 1]; // バナナ
配列のループ処理
var fruits = ["りんご", "バナナ"]; fruits.forEach(function (item, index, array) { console.log(item, index); }); // りんご 0 // バナナ 1
配列の末尾に要素を追加する
var fruits = ["りんご", "バナナ"]; var newLength = fruits.push("みかん"); // ["りんご", "バナナ", "みかん"]
配列の末尾の要素を削除する
var fruits = ["りんご", "バナナ", "みかん"]; var last = fruits.pop(); // 配列の末尾の要素 "みかん" を削除 // ["りんご", "バナナ"];
配列の先頭の要素を削除する
var fruits = ["りんご", "バナナ"]; var first = fruits.shift(); // 配列の先頭の要素"りんご" を削除 // ["バナナ"];
配列の先頭に要素を追加する
var fruits = ["バナナ"]; var newLength = fruits.unshift("いちご") // 配列の先頭に追加 // ["いちご", "バナナ"];
要素のインデックスを取得する
var fruits = ["いちご", "バナナ"]; fruits.push("マンゴー"); // ["いちご", "バナナ", "マンゴー"] var pos = fruits.indexOf("バナナ"); // 1
インデックス位置を指定して要素を削除する
var fruits = ["いちご", "バナナ", "マンゴー"]; var removedItem = fruits.splice(pos, 1); // 指定位置の要素を削除できます // ["いちご", "マンゴー"]
配列をコピーする
var fruits = ["いちご", "マンゴー"]; var shallowCopy = fruits.slice(); // 配列のコピーを作成できます // ["いちご", "マンゴー"]
構文
[element0, element1, ..., elementN]
new Array(element0, element1[, ...[, elementN]])
new Array(arrayLength)
elementN
- JavaScript の配列は、与えられた要素で初期化されます。ただし、
Array
コンストラクタに引数が 1 個だけ与えられ、それが数値である場合を除きます (下記の arrayLength 引数を参照)。これは、Array
コンストラクタで作成された JavaScript 配列にのみ当てはまる特殊なケースで、ブラケット構文 ("[]") で生成された配列リテラルには当てはまらないことに注意してください。 arrayLength
Array
コンストラクタに 0 から 232-1 までの間の整数値 1 個が与えられた場合、その数値の要素数を持つ新しい JavaScript 配列が生成されます。それ以外の数値が与えられた場合、RangeError
が throw されます。
説明
配列は、リストのようなオブジェクトであり、配列に対して横断的な操作や変更を行う組み込みのメソッドを持ちます。JavaScript の配列は、要素数も要素の型も固定されていません。配列のサイズは常に可変であり、データを連続しない位置に格納できるため、JavaScript の配列は密であることが保証されていません (プログラマの使い方次第です)。一般に、これらは便利な特性ではありますが、固定された配列が必要であれば、Typed Array の使用を検討するのも良いでしょう。
人によっては、JavaScript の配列を連想配列として使うべきではないと考えています。連想配列にはプレーンな objects
を使用できますが、こちらにも注意点があります。例として、Lightweight JavaScript dictionaries with arbitrary keys の投稿記事をご覧ください。
配列要素へのアクセス
JavaScript の配列のインデックスは 0 から始まるので、配列の最初の要素はインデックス 0
にあります。そして、最後の要素のインデックスは length
プロパティの値から 1 を引いた値になります。
var arr = ["最初の要素", "2 番目の要素"]; console.log(arr[0]); // ログ : "最初の要素" console.log(arr[1]); // ログ : "2 番目の要素" console.log(arr[arr.length - 1]); // ログ : "2 番目の要素"
toString
が一つのプロパティであるように、配列における配列要素は Array オブジェクトのプロパティです。しかし、次のように配列にアクセスしようとすると、プロパティ名が正しくないため、構文エラーが投げられる事に注意してください:
console.log(arr.0); // 構文エラー
これは、JavaScript の配列とそのプロパティに限った話ではありません。数字から始まるプロパティは、ドット演算子を用いて参照できないため、ブラケット記法を用いる必要があります。例えば '3d'
というプロパティを持つオブジェクトがある場合は、ドット記法ではなくブラケット記法を用いて参照しなければなりません。この類似点を、以下 2 つのコード例で示します:
var years = [1950, 1960, 1970, 1980, 1990, 2000, 2010]; console.log(years.0); // 構文エラー console.log(years[0]); // 正しく動作
renderer.3d.setTexture(model, 'character.png'); // 構文エラー renderer['3d'].setTexture(model, 'character.png'); // 正しく動作
3d
の例で、'3d'
は引用符で括らなければなりません。配列要素へのアクセスにも years[2]
でなく years['2']
を使う事ができますが、必要になることはないでしょう。years[2]
の 2 は最終的に、JavaScript エンジンが内部的に toString
メソッドで型変換することで文字列にされます。これは '2' と '02' が years
オブジェクトの異なる場所を指すようにするためでです。このため、以下の例は true
がログ出力されます:
console.log(years['2'] != years['02']);
同様に、オブジェクトのプロパティ名が偶然にも予約語だった(!) 場合は、ブラケット記法で文字列リテラルを使うことでのみアクセスできます (ただ、少なくとも FireFox 40.0a2 では、ドット記法でアクセスできてしまいます):
var promise = { 'var' : 'text', 'array': [1, 2, 3, 4] }; console.log(promise['array']);
length
と数値プロパティとの関係
JavaScript 配列の length
プロパティと数値プロパティは関連しています。配列の組み込みメソッド (join
、slice
、indexOf
等) は、呼び出された時、配列の length
プロパティの値を考慮します。また、push
、 splice
等の他のメソッドも、配列の length
プロパティを更新します。
var fruits = []; fruits.push('バナナ', 'りんご', 'もも'); console.log(fruits.length); // 3
有効なインデックスを持つ JavaScript 配列の現在のサイズに収まらない位置に要素を追加すると、配列はそれを収められるサイズに拡張され、length
プロパティも更新されます。
var fruits = ['バナナ', 'りんご', 'もも']; fruits[5] = 'マンゴー'; console.log(fruits[5]); // 'マンゴー' console.log(Object.keys(fruits)); // ['0', '1', '2', '5'] console.log(fruits.length); // 6
length
プロパティを直接設定して増やすと以下のように隙間ができます。
var fruits = ['バナナ', 'りんご', 'もも']; fruits[5] = 'マンゴー'; fruits.length = 10; console.log(Object.keys(fruits)); // ['0', '1', '2', '5'] console.log(fruits.length); // 10
length
プロパティのを減らすと、要素が削除されます。
var fruits = ['バナナ', 'りんご', 'もも']; fruits.length = 2; console.log(Object.keys(fruits)); // ['0', '1'] console.log(fruits.length); // 2
これらについては Array.length
ページで詳しく解説します。
match の結果を利用して配列を作成
正規表現と文字列の match の結果から配列を生成できます。この配列には、プロパティと、マッチに関する情報を提供する要素を持ちます。このような配列は、RegExp.exec
、String.match
、そして String.replace
の戻り値です。 これらのプロパティと要素を理解するために、以下の例を見て表を参照してください。
// 1 文字の d、1 文字以上の b、1 文字の d にマッチします // マッチした b およびそれに続く d を記憶します // 大文字小文字は区別しません var myRe = /d(b+)(d)/i; var myArray = myRe.exec("cdbBdbsbz");
このマッチから返されるプロパティと要素は次の通りです:
プロパティまたは要素 | 説明 | 例 |
input |
正規表現がマッチした、元の文字列を反映する読み取り専用プロパティです。 | cdbBdbsbz |
index |
文字列中でマッチした場所を、0 から始まるインデックスで示す読み取り専用プロパティです。 |
1 |
[0] |
最後にマッチした文字列を指定する読み取り専用の要素です。 | dbBd |
[1], ...[n] |
正規表現に含まれる場合、括弧で囲まれたマッチした部分文字列を指定する読み取り専用の要素です。括弧で囲まれた部分文字列の数は無制限です。 | [1]: bB [2]: d |
プロパティ
Array.length
Array
コンストラクタの長さ。値は 1 です。get Array[@@species]
- コンストラクタ関数。 派生オブジェクトを生成する時に使われます。
Array.prototype
- これを使うと全てのArrayオブジェクトにプロパティを追加することができます。
メソッド
Array.from()
- 配列型 (array-like) や反復型 (iterable) オブジェクトから、新しい
Array
インスタンスを生成します。 Array.isArray()
- 配列であれば true を、配列でなければ false を返します。
Array.of()
- 可変個の引数から新しい
Array
インスタンスを生成します。引数の数や型による特別処理はありません。
Array
インスタンス
すべての Array
インスタンスは、Array.prototype
から継承します。コンストラクタの prototype オブジェクトを変更すると、すべての Array
インスタンスに影響を及ぼすことができます。
プロパティ
Array.prototype.constructor
- オブジェクトのプロトタイプを生成する関数を指定します。
Array.prototype.length
- 配列の要素数を反映します。
Array.prototype[@@unscopables]
- このシンボルは、
with
バインディングのスコープから除外されるプロパティ名を保持します。
メソッド
変更メソッド
これらのメソッドは配列を書き換えます。
Array.prototype.copyWithin()
- 配列内の要素を配列内でコピーします。
Array.prototype.fill()
- 配列内で開始位置と終了位置までの要素に固定値で埋めます。
Array.prototype.pop()
- 配列から最後の要素を取得し、戻り値として返します。
Array.prototype.push()
- 配列の最後に 1 つ以上の要素を追加し、新しい配列の長さを返します。
Array.prototype.reverse()
- 配列の要素の順番を逆転させます(最初の要素は最後に、最後の要素は最初になります)。
Array.prototype.shift()
- 配列から最初の要素を取り除き、その要素を返します。
Array.prototype.sort()
- 配列内で要素を整列し、配列を返します。
Array.prototype.splice()
- 配列に対して複数の要素を追加したり取り除いたりします。
Array.prototype.unshift()
- 配列の最初に 1 つ以上の要素を追加し、配列の変更後の長さを返します。
アクセサ メソッド
これらのメソッドは呼び出し対象の配列を書き換えず、配列を何らかの形で表現したものを返します。
Array.prototype.concat()
- この配列に他の配列や値をつないだ、新しい配列を返します。
Array.prototype.includes()
- この配列が特定の要素を含むかどうか判定し、結果をtrueかfalseで返します。
Array.prototype.join()
- 配列の全ての要素をつないだ文字列を返します。
Array.prototype.slice()
- 配列の一部を取り出して新しい配列として返します。
Array.prototype.toSource()
- 指定された配列を表す配列リテラルを返します。この値を使って新しい配列を作れます。
Object.prototype.toSource()
メソッドを上書きしています。 Array.prototype.toString()
- 配列とその要素を表す文字列を返します。
Object.prototype.toString()
メソッドを上書きしています。 Array.prototype.toLocaleString()
- 配列とその要素を表すロケールに従った文字列を返します。
Object.prototype.toLocaleString()
メソッドを上書きしています。 Array.prototype.indexOf()
- 指定された値と等しい値を持つ最初の(添字の一番小さい)要素の添字を返します。見つからない場合、 -1 を返します。
Array.prototype.lastIndexOf()
- 指定された値と等しい値を持つ最後の (添字の一番大きい)要素の添字を返します。見つからない場合、 -1 を返します。
反復メソッド
いくつかのメソッドは引数として、配列を処理する際にコールバックされる関数を取ります。これらのメソッドが呼ばれる際、配列の length
(長さ)を一時記憶するため、コールバック中にこの長さを超えて追加された要素にはアクセスしません。配列に対するその他の変更(要素の値の書き換えや削除)は、変更された要素にメソッドが後でアクセスした場合の操作結果に影響を及ぼす可能性があります。
そのような場合におけるこれらのメソッドの振る舞いは正確に定義されていますが、コードの読者を混乱させないよう、その振る舞いに依存すべきではありません。配列を変化させなければならない場合、代わりに新しい配列にコピーしてください。
Array.prototype.forEach()
- 配列中のそれぞれの要素について関数を呼び出します。
Array.prototype.entries()
- 新しいArray Iteratorオブジェクトを返します。このオブジェクトは配列中の各インデックスに対する キー/値 ペアを保持しています。
Array.prototype.every()
- 配列中の全ての要素が、指定したテスト関数を満たした場合に
true
を返します。 Array.prototype.some()
- 配列中の少なくとも 1 つの要素が、指定したテスト関数を満たした場合に
true
を返します。 Array.prototype.filter()
- 配列中の要素のうち、指定したフィルタリング関数が
true
を返したもの全てを使って新しい配列を生成します。 Array.prototype.find()
- 配列中から、指定したテスト関数を満たす要素の値を返します。一つも見つからない場合は
undefined
を返します。 Array.prototype.findIndex()
-
配列中から、指定したテスト関数を満たす要素のインデックスを返します。一つも見つからない場合は
undefined
を返します。 Array.prototype.keys()
- 新しい
Array Iterator
を返します。このオブジェクトは配列中の各インデックスのキーを保持します。 Array.prototype.map()
- 配列内の全ての要素について与えられた関数を呼び出し、その結果を格納した新しい配列を生成します。
Array.prototype.reduce()
- アキュムレータと配列内の全ての要素に対して (左から右の順番で) 関数を適用し、単一の値に還元します。
Array.prototype.reduceRight()
- アキュムレータと配列内の全ての要素に対して (右から左の順番で) 関数を適用し、単一の値に還元します。
Array.prototype.values()
- 新しい
Array Iterator
オブジェクトを返します。このオブジェクトは、配列中の各インデックスの値を保持します。 Array.prototype[@@iterator]()
- 新しい
Array Iterator
オブジェクトを返します。このオブジェクトは、配列中の各インデックスの値を保持します。
Array
ジェネリックメソッド
Array ジェネリックは非標準、非推奨であり、近い将来に削除される見込みです。 依存した場合は複数のブラウザに対応できないことに留意してください。ただ、GitHub で代用コードを入手 することはできます。
文字列や他の配列のようなオブジェクト (関数の arguments など) に Array のメソッドを適用したいと考える場合があります。こうすると、文字列を文字の配列として扱えます (あるいは、配列ではないものを配列として扱う)。例えば、変数 str に含まれる文字がすべて英字であることをチェックするには、次のように書きます:
function isLetter(character) { return (character >= "a" && character <= "z"); } if (Array.prototype.every.call(str, isLetter)) alert("The string '" + str + "' contains only letters!");
この記法は、どちらかというと無駄であるため、JavaScript 1.6 で汎用的な簡易表記が導入されました:
if (Array.every(isLetter, str)) alert("The string '" + str + "' contains only letters!");
ジェネリックメソッド は String
でも使用できます。
これらは現在 ECMAScript 標準に含まれていません (ただし、これを実現するために ES6 の Array.from()
を使用できます)。以下は、あらゆるブラウザでこれらを可能にするための代用コードです:
// Array の拡張は提供されているものと仮定 (ひとつの方法として、さらにシムを使用します) (function() { 'use strict'; var i, // 下記の方法で array のメソッドを構築することも可能ですが、 // getOwnPropertyNames() メソッドは代用できません: // Object.getOwnPropertyNames(Array).filter(function(methodName) { // return typeof Array[methodName] === 'function' // }); methods = [ 'join', 'reverse', 'sort', 'push', 'pop', 'shift', 'unshift', 'splice', 'concat', 'slice', 'indexOf', 'lastIndexOf', 'forEach', 'map', 'reduce', 'reduceRight', 'filter', 'some', 'every', 'find', 'findIndex', 'entries', 'keys', 'values', 'copyWithin', 'includes' ], methodCount = methods.length, assignArrayGeneric = function(methodName) { if (!Array[methodName]) { var method = Array.prototype[methodName]; if (typeof method === 'function') { Array[methodName] = function() { return method.call.apply(method, arguments); }; } } }; for (i = 0; i < methodCount; i++) { assignArrayGeneric(methods[i]); } }());
例
配列を生成する
次の例では、空の配列「msgArray
」を生成し、msgArray[0]
と msgArray[99]
に値を設定、その後配列の要素数が 100 である事を確認しています。
var msgArray = new Array(); msgArray[0] = "Hello"; msgArray[99] = "world"; if (msgArray.length === 100) { console.log("配列の length は 100 です。"); }
2 次元配列を生成する
以下では、文字列の 2 次元配列としてチェスボードを生成しています。 最初の動きは (6,4) の 'P' を (4,4) にコピーすることでなされます。 古い位置 (6,4) は空白にされます。
var board = [ ['R','N','B','Q','K','B','N','R'], ['P','P','P','P','P','P','P','P'], [' ',' ',' ',' ',' ',' ',' ',' '], [' ',' ',' ',' ',' ',' ',' ',' '], [' ',' ',' ',' ',' ',' ',' ',' '], [' ',' ',' ',' ',' ',' ',' ',' '], ['p','p','p','p','p','p','p','p'], ['r','n','b','q','k','b','n','r'] ]; console.log(board.join('\n') + '\n\n'); // キングの前のポーンを 2 つ前へ移動 board[4][4] = board[6][4]; board[6][4] = ' '; console.log(board.join('\n'));
出力を以下に示します:
R,N,B,Q,K,B,N,R P,P,P,P,P,P,P,P , , , , , , , , , , , , , , , , , , , , , , , , , , , , p,p,p,p,p,p,p,p r,n,b,q,k,b,n,r R,N,B,Q,K,B,N,R P,P,P,P,P,P,P,P , , , , , , , , , , , , , , , , , ,p, , , , , , , , , , p,p,p,p, ,p,p,p r,n,b,q,k,b,n,r
仕様
仕様 | 策定状況 | コメント |
---|---|---|
ECMAScript 1st Edition (ECMA-262) | 標準 | Initial definition. |
ECMAScript 5.1 (ECMA-262) Array の定義 |
標準 | 新メソッド追加: Array.isArray , indexOf , lastIndexOf , every , some , forEach , map , filter , reduce , reduceRight |
ECMAScript 2015 (6th Edition, ECMA-262) Array の定義 |
標準 | 新メソッド追加: Array.from , Array.of , find , findIndex , fill , copyWithin |
ECMAScript 2017 Draft (ECMA-262) Array の定義 |
ドラフト | 新メソッド追加: Array.prototype.includes() |
ブラウザ実装状況
機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|
基本サポート | (有) | (有) | (有) | (有) | (有) |
機能 | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
基本サポート | (有) | (有) | (有) | (有) | (有) | (有) |