配列の内容を関数で処理する際に、プレーンなJavaScriptではforEach()
を、jQueryではeach()
を使いますね。プレーンなJavaScriptにはeach()
というメソッドは存在せず、each()
メソッドはjQueryに実装されています。
いったん整理しておきましょう。
- JavaScriptではforEach()関数が利用可能
- jQueryではeach()関数が利用可能
- JavaScriptではfor()を使うことも出来る
each()
とforEach()
を混同してしまい、利用するシーンでどちらか分からなくなることがあるので整理しておきましょう。
「JavaScript each」で検索してる人結構多いのよね
正しくは「JavaScript forEach」ですね
プレーンなJavaScriptにおけるforEachのチートシートと使い方
forEach()の最も簡単な構成サンプルを記載します。
let sampleArray = [1, 2 , 4, 5, 8192];
sampleArray.forEach(element => {
element++;
console.log(element);
});
上記のコードの実行結果はブラウザのデベロッパーツールのコンソール上に「2」「3」「5」「6」「8193」と表示されますね。サンプルでは、配列内の数値にプラス1をした値が結果として各々出力されます。この形が基本形になります。
コピペ用forEach()チートシート
忘れがちなforEach()の基本形をコピペ用に掲載しておきますので、お使いのエディタ等にスニペット登録しておくことをおすすめします。
sampleArray.forEach(element => {
console.log(element);
});
value, index, arrayを扱う
forEach()の引数には最大3つのパラメータを渡すことが出来ます。それが、value、index、arrayです。2番目のindexと3番目のarrayは省略が出来るので、先ほどのコピペ用のコードがforEach()が最低限動作するコードになります。
ではindex、arrayは何でしょうか?次のサンプルコードを実行することで見えてきます。
let sampleArray = [1, 2 , 4, 5, 8192];
sampleArray.forEach((value, index, _array) => {
console.log('value : ' + value); // 配列の中身の値
console.log('index : ' + index); // 何番目の配列か
console.log('array : ' + _array); // 配列自体
});
このコードを実行すると、コンソールには
value : 1
index : 0
array : [1, 2, 4, 5, 8192]
を1セットとする出力が配列内の個数分(上記の場合だと5個)表示されます。
2個目だと、
value : 2
index : 1
array : [1, 2, 4, 5, 8192]
3個目だと、
value : 4
index : 2
array : [1, 2, 4, 5, 8192]
というような出力結果になりますね。
実行結果を見ると、valueというのは配列の各値、indexというのは0から始まる配列内の何番目かの番号(添字)、arrayはforEach()で回している配列自体、ということが分かります。
添字の開始が0だということに気を付けてください。
そえじ……インデックスがゼロから始まるってことか
これらを理解してからMDN Web Docsの構文を読むと解釈が早くなります。
arr.forEach(callback(currentValue [, index[, array]]) {
// execute something
}[, thisArg]);
currentValueというのがvalue、indexはindex、arrayはarrayと同義です。
callbackとは何でしょうか?
よく見るとcallbackという文字がありますね。このcallbackという文字のせいで、MDN Web Docsの理解が初心者に若干難しくさせているのではないかと思います。
callbackというのは「ある関数(この場合はforEach()関数自体)などを呼び出す際に別の関数などを途中で実行するよう指定する手法(*1)」のことです。(*1 参照:コールバック(callback)とは – IT用語辞典 e-Words)かなり雑な表現になりますが、関数 in 関数ってことでとりあえず覚えておくと良いと思います。
理詰めで説明するよりもまたサンプルコードを見た方が圧倒的に理解が早いので見てみましょう。末尾にある、thisArgについては少々ややこしくなるので次回以降説明する機会を設けます。
let sampleArray = [1, 2 , 4, 5, 8192];
sampleArray.forEach(function(value, index, _array) {
console.log('value : ' + value);
console.log('index : ' + index);
console.log('array : ' + _array);
});
callbackの部分がfunctionになっているのが分かるかと思います。このforEach()関数に入っているfunctionの部分をコールバック関数というんですね。それで、MDN Web Docsにはcallbackと明記していたのです。それにしても急にcallbackって書かれても……って感じですよね。
callback関数に別途定義したfunctionを利用する
これもコードを見た方が早いです。下記はforEach()内に別途作成したfunctionを呼び出して、実行している例です。意外と使用頻度は中くらいなので是非覚えておきましょう。forEach内に独自で定義したfunction()が利用できます。
let sampleArray = [1, 2 , 4, 5, 8192];
function logArrayElements(value, index, _array) {
console.log('Arr[' + index + '] = ' + value)
}
sampleArray.forEach(logArrayElements);
上記のlogArrayElementsが別途定義した関数になります。forEach()内でコールバック関数と使用すると、次のようになります。
sampleArray.forEach(logArrayElements);
3つの引数は既にlogArrayElements()に渡されているのでforEach()内で呼び出す必要はありません。
また、関数を意味する「()」も不要です。(※このfunctionの書き方であればあってもOKです)
ちょっと長くなってしまいましたが、プレーンなJavaScriptにおける基本的なforEach()の使い方でした。何度も言いますが、each()は使えません。each()はjQueryで使用します。
forEach()の応用編
ちょっと補足ですが、forEachで扱う配列には、数値、文字列はもちろん、配列やその他オブジェクトを格納することが出来ます。JavaScriptの配列には基本的に何の型のオブジェクトでも入ります。
下記の改修版サンプルコードには、配列にClassをインスタンス化したオブジェクトを入れ、その配列からClassのメソッドを参照するコードを記載しました。
class Name {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
let member01 = new Name("Hades");
let member02 = new Name("Persephone");
let member03 = new Name("Kerberos");
let classArray = [member01, member02, member03];
classArray.forEach(element => {
let name = element.getName();
console.log(name);
});
このコードの実行結果は、コンソールに
Hades
Persephone
Kerberos
と表示されます。elementにはインスタンス化されたオブジェクトが入っているので、定義したNameクラスの.getName()
で名前を取得出来ます。配列にはオブジェクトも入るということの補足でした。
まとめ
each()はjQueryの関数、forEach()はJavaScriptの関数なのでごっちゃにならないようにご注意ください。
each()ではDOM操作を伴う処理に、forEach()は配列のみを処理する際によく利用します。僕自身、JavaScriptからしばらく離れているとどっちがどっちだったっけ?ってなることがよくあります笑。
何の関数か? | 主な利用シーン | |
forEach() | JavaScript | 配列の処理 |
each() | jQuery | DOM操作 |
自分もごっちゃにならないように記事としてまとめてみました。皆さんのお役にも立てたら光栄です!