.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
は、every
とsome
とは異なり、
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.call
はFunction.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) | ◯ | ◯ | ◯ |
関連項目
© 2017 Mozilla Contributors
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
このページは、ページトップのURL先のMozilla Developer Network(以下、MDN)のコンテンツを翻訳した内容を基に構成されています。 構成について異なる点も含まれますので、下記の項目を確認し、必要に応じて元のコンテンツをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。
- 特定のブラウザに特化しすぎている情報やあまりにも古い情報、 または試験的に導入されているようなAPIや機能については、省略していることがあります。
- 例やデモについて、実際にページ内で動作させる関係で一部ソースコードを変更している場合や、 その例で使用しているコンテンツの単語や文章などを日本人向けに変更しいてる場合があります。
- MDNの更新頻度が高いため、元のコンテンツと比べ情報が古くなっている可能性があります。
- "訳注:"などの断わりを入れた上で、日本人向けの情報の追記を行っている事があります。