実践JavaScript
forEach と map
このレッスンで分かること
forEachは副作用用、戻り値undefined、チェーン不可mapは変換用、新しい配列を返す、チェーン可能- 変換結果が欲しいなら
map、副作用 (ログ / DOM 操作) ならforEach- コールバックの引数は
(element, index, array)の 3 つ
forEach と map とは
forEachとmapの違いと使い分けを理解しよう。本レッスンでは、forEach と map の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
forEach と map
配列の各要素に対して処理を行う2つの基本メソッド、forEachとmapの使い分けを学びましょう。
コールバック関数とは
高階関数に渡す関数のことをコールバック関数と呼びます。
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); // undefinedmap:新しい配列を作る
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 の違い
| 特徴 | forEach | map |
|---|---|---|
| 戻り値 | 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(...); // エラー!コールバック関数の引数
forEachとmapのコールバック関数は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の戻り値を使わない ─ 副作用だけならforEach、mapの戻り値を捨てるのは設計ミスforEachでasync/await─forEachは Promise を待たない。for-ofかPromise.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 つができることを確認しましょう。
- forEach と map の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. forEach と map とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン