解説
mapした結果とforEachの返り値は何が違う?配列の変換を作例で試そう
同じ三つの数を2倍にし、mapの配列とforEachのundefinedを比較。returnの書き忘れと、元の配列への変更の注意も確認する。

配列の数を2倍にしたい。forEachの中で計算したのに、呼び出した結果を変数へ入れるとundefinedだった。配列のmapとforEachは、同じように要素を扱えても返すものが違うよ。
今回は[1,2,3]だけで比べる。ブラウザの作例で計算と結果を見られ、保存や外部への送信はしないよ。
mapは、返した値を集める
const values = [1, 2, 3];
const doubled = values.map(value => value * 2);
console.log(doubled); // [2, 4, 6]
console.log(values); // [1, 2, 3]
mapは各要素に対する関数の返り値から、新しい配列を作る。今回は、value * 2という計算の結果が集まるんだ。
元の値を直接書き換えない関数なので、この例ではvaluesも元のまま残る。「新しい結果の配列がほしい」という目的と合っているね。
forEachの返り値はundefined
const values = [1, 2, 3];
const result = values.forEach(value => value * 2);
console.log(result); // undefined
console.log(values); // [1, 2, 3]
forEachは、各要素へ処理を実行するためのもの。中の関数から計算値を返しても、それを結果の配列として集めるメソッドではないよ。
undefinedは、ここでは値が返されていないことを表す。計算した内容をconsoleへ出すなどの処理はできるけれど、forEach自体の返り値が配列になるわけではない。
波カッコを付けると、returnが必要な形になる
const values = [1, 2, 3];
const result = values.map(value => { value * 2; });
console.log(result); // [undefined, undefined, undefined]
この形では関数の処理を波カッコで囲み、値を返すreturnを書いていない。map自体は配列を作るけれど、中身が計算した数にならないんだ。
この例なら、return value * 2;と書くか、最初の例のように式を直接返す形へする。計算が走ったかだけでなく、何を返したかを確認しよう。
作例で三つの結果を見る
- mapを選び、「実行する」を押す。結果は[2,4,6]。
- forEachへ変え、同じ計算をしても返り値はundefinedになることを見る。
- returnなしのmapを選び、配列の各要素がundefinedになることを確認する。
- 「最初から試す」でmap・未実行へ戻す。
処理中に計算した値と、メソッドの返り値は別々に表示する。各実行は新しい[1,2,3]から始め、前の操作の影響は持ち越さないよ。
mapなら中身も独立する、とは限らない
今回は数だけの配列。オブジェクトを同じ参照のまま返せば、その中身を共有することがあるし、関数の中で元の要素を書き換えることもできる。
「mapを使ったから、元のデータへの変更が絶対にない」とは決めないようにしよう。今回の関数が何をするかと、新しい配列を返すことを分けて考えたいね。
編集部ではNode.jsとChromiumで三つの返り値、計算値、元の配列とリセットを確認した。要素を探す場合はfindとfilter、入れ子の共有は浅いコピーとstructuredCloneも参考になるよ。
動かしてみよう:計算値と返り値
map・forEach・returnなしのmapを実行し、計算した値と結果を比べよう。

みんなのコメント 0
感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。
最初のコメントをどうぞ。