1. forEach とは?
forEach は、JavaScript の配列や NodeList、Map、Set などの反復可能なオブジェクトに対して、各要素に対して繰り返し処理を実行 できるメソッドです。
ポイント:通常の
forループと異なり、forEachを使うと シンプルに記述 できますが、breakやreturnでループを抜けることはできなくなります。
forEach を使用できるオブジェクトの例:
- 
Array(配列) - 
NodeList(querySelectorAllの結果) - 
Map(キーと値のペアを保持するデータ構造) - 
Set(重複のない値を保持するデータ構造) - 
TypedArray(型付き配列Uint8Arrayなど) - 
Iterator(2023年以降に追加) 
Iterator.prototype.forEach は 2023 年以降に追加されたため、Iterator に対しても forEach を使用可能になりました。
補記:prototype とはオブジェクトの継承機能であり、特定のオブジェクトに共通のメソッドを提供する仕組みです。
例えば、Array.prototype.forEach は配列専用の forEach メソッドであり、Iterator.prototype.forEach はイテレーター専用の forEach メソッドを指します。
この仕組みのおかげで、オブジェクトごとに個別に forEach を定義するのではなく、prototype を利用して共通の機能を提供できます。
2. forEach の基本構文
array.forEach((要素, インデックス, 配列) => {
    // 繰り返し処理
});
- 
要素:現在の要素の値 - 
インデックス(省略可):現在の要素のインデックス(0 から始まる) - 
配列(省略可):元の配列全体 
3. forEach の基本的な使い方
例1:配列の各要素を表示
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(num => {
    console.log(num);
});
//出力:
//1 2 3 4 5
例2:インデックスを含めて出力
const fruits = ["りんご", "バナナ", "ぶどう"];
fruits.forEach((fruit, index) => {
    console.log(`${index}: ${fruit}`);
});
//出力:
//0: りんご
//1: バナナ
//2: ぶどう
4. forEach の活用
querySelectorAll との併用
querySelectorAll は NodeList を返しますが、forEach を使ってループ処理が可能です。
const items = document.querySelectorAll(".item");
items.forEach(item => {
    item.style.color = "red";
});
// すべての .item 要素の文字色を赤に変更
5. forEach と for ループの違い
| 比較項目 | forEach | 
for ループ | 
|---|---|---|
| 記述の簡潔さ | ◎ 短く書ける | △ やや長くなる | 
| ループの途中終了 | ✖ break できない | 
◎ break 可能 | 
return の扱い | 
✖ return できない | 
◎ return 可能 | 
例3:forEach vs for
const numbers = [1, 2, 3, 4, 5];
// forEach(ループを途中で抜けられない)
numbers.forEach(num => {
    if (num === 3) {
        return; // ループは止まらない(単なる関数のreturnで、ループには影響しない)
    }
    console.log(num);
});
// 出力:
// 1
// 2
// 4
// 5
// for ループ(break で終了可能)
for (let i = 0; i < numbers.length; i++) {
    if (numbers[i] === 3) {
        break; // ループ終了
    }
    console.log(numbers[i]);
}
// 出力:
// 1
// 2
6. map との違い
forEach と map は似ていますが、map は新しい配列を返す のに対し、forEach は配列を変更せずに処理を実行します。
const numbers = [1, 2, 3, 4, 5];
// forEach(結果を返さない)
numbers.forEach(num => num * 2);
console.log(numbers); // [1, 2, 3, 4, 5]
// map(新しい配列を返す)
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
データを変換したいなら
map、処理を実行するだけならforEach
7. Iterator.prototype.forEach の登場(2023年以降)
これまで forEach は Array や NodeList などに使われていましたが、2023 年以降 Iterator にも forEach メソッドが追加 されました。
Iterator.prototype.forEach の特徴
- 逐次取得 するため、メモリ効率が良い(全データをメモリに展開しない)
 - 
Set.values()やMap.keys()などのイテレーターにも適用可能 
コンソールで、
console.log(Array.prototype);
や
console.log(Iterator.prototype);
とすると、ArrayやIteratorが持っているメソッドを確認できる
8. Iterator(イテレーター)とは?
Iteratorとは、データを1つずつ順番に取得できるオブジェクトです。
.next() メソッドを持ち、データを逐次取得する仕組みを提供します。
Iteratorの基本的な動作
const iterator = [1, 2, 3][Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { done: true } // 処理が終了した合図
Iterator は .next() を使って順番に値を取得できる。
配列 や Set や Map はデフォルトで Iterator ではなく Iterable。 Iterator を取得するには Symbol.iterator を使う。
あるいは、array.values() や set.values()、map.keys() を使うと Iterator を取得できる。
const set = new Set(["a", "b", "c"]);
const iterator = set.values();
console.log(iterator.next()); // { value: "a", done: false }
Symbol.iterator を持つデータ型
以下のデータ型は Symbol.iterator を持っており、Iterator を作成できます。
- 
Array(配列) - 
String(文字列) - 
Set(集合) - 
Map(連想配列) - 
arguments(関数の引数オブジェクト) - 
NodeList(DOMの querySelectorAll などで取得されるリスト) - 
TypedArray(Uint8Array や Float32Array などの型付き配列) 
Symbol.iterator を持つか確認する方法
console.log(typeof Array.prototype[Symbol.iterator]);  // function
console.log(typeof String.prototype[Symbol.iterator]); // function
console.log(typeof Set.prototype[Symbol.iterator]);    // function
console.log(typeof Map.prototype[Symbol.iterator]);    // function
console.log(typeof arguments[Symbol.iterator]);        // function(関数の中で確認)
console.log(typeof NodeList.prototype[Symbol.iterator]); // function(`querySelectorAll` で取得した要素群)
これらのオブジェクトは Symbol.iterator を持っているため、for...of や Iterator.prototype.forEach を適用可能!
9. Iterator.prototype.forEach
☑️ Iterator に forEach を使う
Iterator.prototype.forEach は、Iteratorの forEach メソッド であり、Iterator に対して forEach を適用することができます。
const set = new Set(["apple", "banana", "cherry"]);
set.values().forEach(fruit => {
    console.log(fruit);
});
// 出力:
// apple
// banana
// cherry
Set ではなく、Iterator に対して forEach を適用している!
逐次取得(1つずつ処理)するため、メモリ使用量を抑えられる!
10. Iterator.prototype.forEach の対応状況
Iterator.prototype.forEach は 比較的新しい技術(2023年以降) であり、すべてのブラウザでサポートされているわけではありません。
対応状況を確認するサイト
最新の対応状況は、以下のサイトで確認できます。
Iterator.prototype.forEach を使用する際は、古いブラウザでの動作に注意が必要です!
11. まとめ
☑️ forEach は配列や NodeList に対して 繰り返し処理 を適用できる
☑️ for ループよりも 簡潔に書けるが、途中終了は不可
☑️ querySelectorAll の NodeList に対しても利用可能
☑️ map との違いを理解し、適切に使い分ける
☑️ 2023 年以降 Iterator.prototype.forEach が追加され、Iterator にも forEach を適用できるようになった
☑️ Iterator.prototype.forEach はストリーム処理など、大量データを扱う場面で特に有効
☑️ Iterator.prototype.forEach は比較的新しい技術であり、古いブラウザでは対応していない可能性があるため注意!
forEach を適切に活用し、効率的なループ処理を実装しよう!