Array.prototype.forEach()

概要

与えられた関数を、配列の各要素に対して一度ずつ実行します。

構文

array.forEach(callback[, thisObj]);

引数

callback
各要素に対して実行するコールバック関数で、3つの引数をとります。
currentValue
現在処理されている配列の要素
index
現在処理されている配列の要素のインデックス
array
forEachが適用されている配列
thisObj
任意。callback 内で this として使用する値

説明

forEach は、与えられた関数 (callback)を配列に含まれる各要素に対して一度ずつ呼び出します。callback は値が代入されている配列のインデックスに対してのみ呼び出されます。つまり、すでに削除されたインデックスや、明示的に undefined を代入して初期化されたインデックス、まだ値が代入されていないインデックスに対しては呼び出されません。

callback は、要素の値、要素のインデックス、走査されている Array オブジェクトという 3 つの引数をともなって呼び出されます。

forEachthisObject パラメータが与えられると、callback の呼び出しのたびにそのオブジェクトが this として使用されます。thisObject が与えられないか null だと、callback に結び付けられたグローバルオブジェクトが代わりに使用されます。

forEach は呼び出された配列を変化させません。

forEach によって処理される配列要素の範囲は、callback が最初に呼び出される前に設定されます。forEach の呼び出しが開始された後に追加された配列要素に対しては、callback は実行されません。既存の配列要素が変更または削除された場合、callback に渡される値は forEach がそれらを参照した時点での値になります。削除された配列要素を参照することはありません。

互換性

forEach は ECMA-262 標準への最近の追加であり、他の版の標準実装には存在しない場合があります。次のコードをスクリプトの先頭に記述する事により、forEach がネイティブでサポートされていない環境でもこれを使用する事が可能となります。これは ECMA-262 第 5 版で定められたアルゴリズムと全く同じものです。ObjectTypeError はそれぞれオリジナルの値を持ち、またそれらの callback.callFunction.prototype.call のオリジナルの値として評価されます。

// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://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: http://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
基本サポート ? ? ? ? ?

Kangax's compat tablesに基づく。

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

 このページの貢献者: kkas, teoli, ethertank, Potappo, Shoot
 最終更新者: kkas,