0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ぼくのJavaScript備忘録】 forEach の使い方徹底解説

Last updated at Posted at 2025-02-04

1. forEach とは?

forEach は、JavaScript の配列や NodeListMapSet などの反復可能なオブジェクトに対して、各要素に対して繰り返し処理を実行 できるメソッドです。

ポイント:通常の for ループと異なり、forEach を使うと シンプルに記述 できますが、breakreturn でループを抜けることはできなくなります。

forEach を使用できるオブジェクトの例:

  • Array(配列)
  • NodeListquerySelectorAll の結果)
  • 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 との併用

querySelectorAllNodeList を返しますが、forEach を使ってループ処理が可能です。

const items = document.querySelectorAll(".item");
items.forEach(item => {
    item.style.color = "red";
});
// すべての .item 要素の文字色を赤に変更

5. forEachfor ループの違い

比較項目 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 との違い

forEachmap は似ていますが、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年以降)

これまで forEachArrayNodeList などに使われていましたが、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() を使って順番に値を取得できる。

配列SetMap はデフォルトで Iterator ではなく IterableIterator を取得するには 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年以降) であり、すべてのブラウザでサポートされているわけではありません。

対応状況を確認するサイト

最新の対応状況は、以下のサイトで確認できます。

Can I use

MDN

Iterator.prototype.forEach を使用する際は、古いブラウザでの動作に注意が必要です!


11. まとめ

☑️ forEach は配列や NodeList に対して 繰り返し処理 を適用できる
☑️ for ループよりも 簡潔に書けるが、途中終了は不可
☑️ querySelectorAllNodeList に対しても利用可能
☑️ map との違いを理解し、適切に使い分ける
☑️ 2023 年以降 Iterator.prototype.forEach が追加され、Iterator にも forEach を適用できるようになった
☑️ Iterator.prototype.forEach はストリーム処理など、大量データを扱う場面で特に有効
☑️ Iterator.prototype.forEach は比較的新しい技術であり、古いブラウザでは対応していない可能性があるため注意!

forEach を適切に活用し、効率的なループ処理を実装しよう!

0
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?