概要
与えられた関数を、配列の各要素に対して一度ずつ実行します。
構文
array.forEach(callback[, thisObj]);
引数
callback
- 各要素に対して実行するコールバック関数で、3つの引数をとります。
currentValue
- 現在処理されている配列の要素
index
- 現在処理されている配列の要素のインデックス
array
forEach
が適用されている配列
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 |
---|---|---|---|---|---|
基本サポート | ? | ? | ? | ? | ? |