実践JavaScript

forEach と map

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

このレッスンで分かること

  • forEach は副作用用、戻り値 undefined、チェーン不可
  • map は変換用、新しい配列を返す、チェーン可能
  • 変換結果が欲しいなら map、副作用 (ログ / DOM 操作) なら forEach
  • コールバックの引数は (element, index, array) の 3 つ

forEach と map とは

forEachとmapの違いと使い分けを理解しよう。本レッスンでは、forEach と map の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

forEach と map

配列の各要素に対して処理を行う2つの基本メソッド、forEachmapの使い分けを学びましょう。

コールバック関数とは

高階関数に渡す関数のことをコールバック関数と呼びます。

JavaScript

// numbers.map() に渡す (n) => n * 2 がコールバック関数 const doubled = [1, 2, 3].map((n) => n * 2);

forEach:副作用のための繰り返し

forEachは各要素に対して処理を実行しますが、戻り値はundefinedです。

JavaScript

const fruits = ["りんご", "バナナ", "みかん"]; // 各要素をログ出力(副作用) fruits.forEach((fruit, index) => { console.log(`${index + 1}. ${fruit}`); }); // 出力: // 1. りんご // 2. バナナ // 3. みかん // forEachの戻り値はundefined const result = fruits.forEach(f => f.toUpperCase()); console.log(result); // undefined

map:新しい配列を作る

mapは各要素を変換し、新しい配列を返します。元の配列は変更されません。

JavaScript

const numbers = [1, 2, 3, 4, 5]; // 各要素を2倍にした新しい配列 const doubled = numbers.map(n => n * 2); console.log(doubled); // [2, 4, 6, 8, 10] console.log(numbers); // [1, 2, 3, 4, 5](元は変わらない) // オブジェクトの変換 const users = [ { name: "太郎", age: 25 }, { name: "花子", age: 30 } ]; const names = users.map(user => user.name); console.log(names); // ["太郎", "花子"]

forEach と map の違い

特徴forEachmap
戻り値undefined新しい配列
用途副作用(ログ出力、DOM操作など)データの変換
チェーンできないできる

JavaScript

const prices = [100, 200, 300]; // map → filter のチェーン const taxedExpensive = prices .map(p => p * 1.1) // 税込み価格 .filter(p => p > 150); // 150円以上 // [220, 330] // forEach ではチェーンできない // prices.forEach(...).filter(...); // エラー!

コールバック関数の引数

forEachmapのコールバック関数は3つの引数を受け取れます。

JavaScript

const arr = ["a", "b", "c"]; arr.forEach((element, index, array) => { console.log(`[${index}] ${element} (配列長: ${array.length})`); }); // [0] a (配列長: 3) // [1] b (配列長: 3) // [2] c (配列長: 3)

使い分けの判断基準

  • 変換結果が必要mapを使う
  • 副作用だけが目的forEachを使う
  • 迷ったらmapを使う(より関数型で安全)

JavaScript

// mapを使うべきケース const uppercased = words.map(w => w.toUpperCase()); // forEachを使うべきケース items.forEach(item => { database.save(item); // 外部への副作用 });

実務で遭遇するパターン

中級レッスンで学んだことが、実際の業務コードでどう登場するかを整理します。

  • DOM 操作items.forEach(el => el.classList.add("selected"))
  • API レスポンスの整形users.map(u => ({ id: u.id, name: u.name }))
  • ログ出力errors.forEach(err => console.error(err))
  • React レンダリングitems.map(item => <Item key={item.id} {...item} />)

コードレビューで指摘されがちなポイント

PR を出すとシニアから入りやすい指摘です。先回りで身につけておけばレビューが一発で通ります。

  • map の戻り値を使わない ─ 副作用だけなら forEachmap の戻り値を捨てるのは設計ミス
  • forEachasync/awaitforEach は Promise を待たない。for-ofPromise.all(items.map(...))
  • ループ内で外部変数を変更reduce のほうが意図明確
  • チェーンが長すぎ.filter().map().filter().map() の連続は読みづらい、変数で区切る

パフォーマンス考慮事項

  • for ループのほうが若干速い ─ 配列メソッドはコールバック呼び出しのコスト分遅い
  • JIT で最適化 ─ ホットパス以外なら気にしないでよい
  • チェーンは複数パス.filter().map() は 2 回回す、reduce で 1 回にまとめられる
  • map のメモリ確保 ─ 新しい配列を生成するので大量データではメモリに注意
この章のポイント

ここまでの要点 forEach は副作用、map は変換。async には for-of、過剰チェーンは避ける。戻り値を使う / 使わないで使い分け。

よくある質問

Q. 実務ではどんな場面でこの知識を使いますか?

A. API クライアントの実装、フロントエンドのフレームワーク内ロジック、Node.js のサーバーサイドなど幅広く登場します。React/Vue などのフレームワークもこの基礎の上に成り立っているため、ここで身につけた知識は資産になります。

Q. コードレビューで指摘されやすいポイントは?

A. var の使用、== の使用、無駄なネストの深さ、命名の曖昧さなどが頻出指摘です。Linter(ESLint)と Prettier を導入すれば機械的に防げる指摘が多いため、まずはツールで自動化するのが効率的です。

Q. 次に学ぶべき内容は何ですか?

A. Promise・async/await が理解できたら、fetch を使った API 連携、Web フレームワーク(React/Vue/SvelteKit)、ビルドツール(Vite/Webpack)に進むのがおすすめです。実プロジェクトでアウトプットしながら学ぶと定着が早まります。

次のレッスン

次は filter と find で、forEachとmapの違いと使い分けを理解しよう を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. forEach と map の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. forEach と map とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン