🔰

【JS初級】#1 mapメソッドとforEachメソッドの違い・使い分け【3分解説】

2024/08/15に公開

まえがき

今回から始まりました、JavaScript(TypeScript)解説シリーズ。実務でJavaScript(TypeScript)を使っている人も、勉強中の人も、「あれ?言われてみればどうだったっけ?」となるような疑問を解決していこうというコーナーです。今後はもっと踏み込んだ内容も執筆していきたいと思っています。

今回のテーマ

第一回のテーマはmapメソッドとforEachメソッドです。どちらもよく使われることのあるメソッドですが、違いを正しく理解せずに使っている方も中にはいるのではないでしょうか。今回はこの二つのメソッドの違いについて解説します。

例題

const arrayA = [0, 1, 2, 3];

arrayA.forEach((elm)=>{
    return elm += 1;
    })

console.log(arrayA);
Q.このコードを実行した際のコンソールの表示はどのようなものになりますか?(トグルを開いて答えを表示)

A.

[0, 1, 2, 3]

非破壊的メソッドのforEachは、元の配列に変更を加えません。

結論

  • mapメソッド → 配列の各要素に対し操作を行い、その結果を要素に持つ新しい配列を返すメソッド。非破壊的。
  • forEachメソッド → 配列の各要素に対し操作を行うメソッド。非破壊的。

mapメソッドは既存の配列の要素から、新しい配列を作成するという目的がある場合に用いられます。
逆にいえば、ただただ配列の要素に対して何かを実行したいだけであればforEachメソッドを使うのが良いということになります。

基本的に、配列を返したいかどうかで使い分けると覚えればOKです。

どちらのメソッドも非破壊的メソッドなので、元の配列が書き換えられることはありません。先ほどの問題で出力結果が[1, 2, 3, 4]になると思ってしまった方もいたのではないでしょうか。
(じゃあさっきの例題の return elm += 1; はなんだったのかというと、何でもないです。この返り値はどこにも保存されず、即破棄されます。)

map forEach
共通点 配列の各要素に操作を行いたい 配列の各要素に操作を行いたい
相違点 結果から配列を作りたい 操作だけ行って何も返す必要がない

map

const numbers = [1, 2, 3, 4, 5];

const doubledNumbers = numbers.map((number) => {
  return number * 2;
});

console.log(doubledNumbers);

// [2, 4, 6, 8, 10]

各要素を2倍にしたものを要素に持つ、新しい配列を定義できました。numbers配列はそのままです。

forEach

const numbers = [1, 2, 3, 4, 5];

numbers.forEach((number) => {
  console.log(number * 2);
});

// 2
// 4
// 6
// 8
// 10

配列の各要素に対し、2倍にした値をコンソールで出力しました。numbers配列はそのままです。

終わりに

今回はmapメソッドとforEachメソッドについての違い・使い分けを解説しました。ですが、ぶっちゃけてしまうとforEachメソッドは使わないことが多いです。理由としては

  • forEachでやりたい大体のことは他のメソッドでより簡潔に書くことができる
  • 返り値がない関数の実行があまりない

などがあります。実務で使った例としては、Reactで開発してる際にforEachで配列内の要素を次々にsetState(elm)した位しか記憶にないです。
逆に、フロントエンドのタスクを消化している日のほとんどでmapメソッドは使います。

CS専攻の人が考えつきがちな、不必要なforEachメソッドを使ったコードにこんなものがあります。

let total = 0;
const numbers = [5, 10, 15];

numbers.forEach((number) => {
  total += number;
});

console.log(`Total sum: ${total}`);

配列の要素の数値の合計を求めるコードですが、僕もCS専攻でC言語をゴリゴリに書いていたので、JavaScript始めたての時はこのようなコードを書こうとしてしまっていたかもしれません。
このコードは以下のように書き換えることができます。

const numbers = [5, 10, 15];

const total = numbers.reduce((acc, number) => acc + number, 0);

console.log(`Total sum: ${total}`);

reduceメソッドを使うことで、簡潔に、そして不要なletを用いずにコードを書くことができました。
他にも、

  • 配列内の特定要素をforEachで探す→find
  • 配列内でとある条件を満たすものだけを集める→filter
  • 配列内でとある条件を満たすものだけに対し操作を行い配列を作る(forEach&push)→filter&map

という風に、よく考えてみれば考えてみるほど、forEachを使わなければいけない場面は少ないと感じます。

今回の解説で、mapforEachの違いを理解し、正しく使い分けられるようになったり、リファクタリングの手助けになったりすれば幸いです。

(次回はTypeScriptの内容にしようと考えています。お読み頂きありがとうございました🙌)

Discussion