.forEach()

forEach()メソッドは、配列要素ごとに提供された関数を実行します。

文法

arr.forEach(callback[, thisArg])
引数 説明
callback 各要素で実行する関数を指定します。
[thisArg] コールバック実行時にthisとして使用される値を指定します。

説明

forEachは昇順で、配列内の各要素に対して提供されたcallbackを実行します。 削除、または省略されたインデックスでは実行されません。 ただし、undefined値を持つ提供されている要素では実行されます。

callbackは、下記の3つの引数を使用して実行されます。

  • 要素の値
  • 要素のインデックス
  • 巡っている配列

もしthisArgパラメーターがforEachに提供された場合、 実行時にcallback関数に渡され、そのthis値として使用されます。 そうでなければ、this値としてundefined値が渡されます。 callbackによって最終的に供給されるthis値は、 関数によるthisの取り扱いの通常の規則に沿って決定されます。(翻訳に自信なし)

コールバックの最初の実行前に、forEachによって設定された要素の範囲が処理されます。 forEachが呼び出された後に追加された要素は、callbackの対象にはなりません。 もし配列内の要素が変更された場合は、 forEachがそれらの値を参照する時の値でcallbackに渡され、 削除された要素であれば、その渡す対象から外されます。

注意: forEachのループを停止またはbreakする手段は存在しません。 解決策に、Array.everyまたはArray.someがあり、 その例については後述します。

forEachは、everysomeとは異なり、 callback関数を一度に配列の各要素に実行し、常にundefined値を返します。

配列の内容を出力

下記のコードは、配列内の各要素をログ出力します。

function logArrayElements(element, index, array) {
    console.log("a[" + index + "] = " + element);
}

// インデックス番号2はメンバでは無いため、
// 対象になりません。
[2, 5, , 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[3] = 9

ループのbreak

下記のコードは.every(Array.prototype.every)を使用して配列の内容のログ出力と、 与えられたTHRESHOLD(境界値)より大きな値に達した際の停止を行っています。

var THRESHOLD = 12;
var v = [5, 2, 16, 4, 3, 18, 20];
var res;

res = v.every(function(element, index, array) {
    console.log("element:", element);
    if (element >= THRESHOLD) {
        return false;
    }

    return true;
});
console.log("res:", res);
// logs:
// element: 5
// element: 2
// element: 16
// res: false

res = v.some(function(element, index, array) {
    console.log("element:", element);
    if (element >= THRESHOLD) {
        return true;
    }

    return false;
});
console.log("res:", res);
// logs:
// element: 5
// element: 2
// element: 16
// res: true

オブジェクトをコピーする関数

下記のコードは与えられたオブジェクトのコピーを作成します。 オブジェクトをコピーする様々な方法が存在しますが、下記はその中の1つの方法であり、 ECMAScript 5のObject.*のメタプロパティ関数を使用し、 Array.prototype.forEachをどのように動作させているかを示したものです。

function copy(o) {
  var copy = Object.create(Object.getPrototypeOf(o));
  var 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};
var o2 = copy(o1); // これで、o2はo1のように見えます。(参照ではなく、同じ構造を持つ)

Polyfill

forEachは、5thエディションのECMA-262標準で追加されたため、 標準実装の全てに提供されていないかもしれません。 あなたのスクリプトが始まる前に下記のコードを挿入することで、 ネイティブでECMA-262実装のforEachがサポートされない環境でも、forEachが使用可能になります。 このアルゴリズムは、5thエディションのECMA-262の正確な仕様の1つであり、 ObjectとTypeErrorはそれらの元の値を持つとみなし、 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;

    // 4. If IsCallable(callback) is false, throw a TypeError exception.
    // See: http://es5.github.com/#x9.11
    if (typeof callback !== "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
  };
}

仕様

ブラウザ互換性

デスクトップ
機能 Chrome Firefox
(Gecko)
IE Opera Safari
基本 1.5 (1.8) 9
モバイル
機能 Android Chrome for
Android
Firefox
Mobile
IE
Mobile
Opera
Mobile
Safari
Mobile
基本 1.0 (1.8)

関連項目

 Back to top

© 2017 Mozilla Contributors
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.

このページは、ページトップのURL先のMozilla Developer Network(以下、MDN)のコンテンツを翻訳した内容を基に構成されています。 構成について異なる点も含まれますので、下記の項目を確認し、必要に応じて元のコンテンツをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。

  • 特定のブラウザに特化しすぎている情報やあまりにも古い情報、 または試験的に導入されているようなAPIや機能については、省略していることがあります。
  • 例やデモについて、実際にページ内で動作させる関係で一部ソースコードを変更している場合や、 その例で使用しているコンテンツの単語や文章などを日本人向けに変更しいてる場合があります。
  • MDNの更新頻度が高いため、元のコンテンツと比べ情報が古くなっている可能性があります。
  • "訳注:"などの断わりを入れた上で、日本人向けの情報の追記を行っている事があります。