【JS初級】#1 mapメソッドとforEachメソッドの違い・使い分け【3分解説】
まえがき
今回から始まりました、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
を使わなければいけない場面は少ないと感じます。
今回の解説で、map
とforEach
の違いを理解し、正しく使い分けられるようになったり、リファクタリングの手助けになったりすれば幸いです。
(次回はTypeScriptの内容にしようと考えています。お読み頂きありがとうございました🙌)
Discussion