概要
与えられた関数を、配列の各要素に対して一度ずつ実行します。
構文
array.forEach(callback[, thisObj]);
引数
callback- 各要素に対して実行するコールバック関数で、3つの引数をとります。
currentValue- 現在処理されている配列の要素
index- 現在処理されている配列の要素のインデックス
arrayforEachが適用されている配列
thisObj任意。callback内でthisとして使用する値
説明
forEach は、与えられた関数 (callback)を配列に含まれる各要素に対して一度ずつ呼び出します。callback は値が代入されている配列のインデックスに対してのみ呼び出されます。つまり、すでに削除されたインデックスや、明示的に undefined を代入して初期化されたインデックス、まだ値が代入されていないインデックスに対しては呼び出されません。
callback は、要素の値、要素のインデックス、走査されている Array オブジェクトという 3 つの引数をともなって呼び出されます。
forEach に thisObject パラメータが与えられると、callback の呼び出しのたびにそのオブジェクトが this として使用されます。thisObject が与えられないか null だと、callback に結び付けられたグローバルオブジェクトが代わりに使用されます。
forEach は呼び出された配列を変化させません。
forEach によって処理される配列要素の範囲は、callback が最初に呼び出される前に設定されます。forEach の呼び出しが開始された後に追加された配列要素に対しては、callback は実行されません。既存の配列要素が変更または削除された場合、callback に渡される値は forEach がそれらを参照した時点での値になります。削除された配列要素を参照することはありません。
互換性
forEach は ECMA-262 標準への最近の追加であり、他の版の標準実装には存在しない場合があります。次のコードをスクリプトの先頭に記述する事により、forEach がネイティブでサポートされていない環境でもこれを使用する事が可能となります。これは ECMA-262 第 5 版で定められたアルゴリズムと全く同じものです。Object と TypeError はそれぞれオリジナルの値を持ち、またそれらの callback.call は Function.prototype.call のオリジナルの値として評価されます。
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: https://es5.github.com/#x15.4.4.18
if ( !Array.prototype.forEach ) {
Array.prototype.forEach = function( callback, thisArg ) {
var T, k;
if ( this == null ) {
throw new TypeError( " this is null or not defined" );
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0; // Hack to convert O.length to a UInt32
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: https://es5.github.com/#x9.11
if ( {}.toString.call(callback) != "[object Function]" ) {
throw new TypeError( callback + " is not a function" );
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if ( thisArg ) {
T = thisArg;
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while( k < len ) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if ( k in O ) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[ k ];
// ii. Call the Call internal method of callback with T as the this value and
// argument list containing kValue, k, and O.
callback.call( T, kValue, k, O );
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
例
配列の内容を出力する
次のコードは配列の要素毎に、コンソールに 1 行づつ要素の内容を出力します。
function logArrayElements(element, index, array) {
console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[2] = 9
オブジェクトをコピーする関数
次のコードは与えられたオブジェクトのコピーを生成します。オブジェクトのコピーを生成するには他にもいくつか方法がありますが、ここでは Array.prototype.forEach の動作を説明する為に、forEach を選択しています。またここでは、ECMA-262 第 5 版で新たに仕様に追加されたオブジェクトのメソッドを使用しているという点に留意して下さい。
function copy(o) {
var copy = Object.create( Object.getPrototypeOf(o) ),
propNames = Object.getOwnPropertyNames(o);
propNames.forEach(function(name){
var desc = Object.getOwnPropertyDescriptor(o, name);
Object.defineProperty(copy, name, desc);
});
return copy;
}
var o1 = {a:1, b:2},
o2 = copy(o1); // o1 のコピーが o2 に代入される
ブラウザ実装状況
| 機能 | Firefox (Gecko) | Chrome | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| 基本サポート | (有) | 1.5 | 9 | (有) | (有) |
| 機能 | Firefox Mobile (Gecko) | Android | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|
| 基本サポート | ? | ? | ? | ? | ? |