forEach で配列をまわす
このレッスンで分かること
配列.forEach((要素) => { 処理 })で、配列が自分をまわしてくれますforEachは途中でbreakできません
ループの決まり文句を、毎回書いている
for (let i = 0; i < works.length; i++) は、やりたいことに比べて長すぎます。しかも初期値、条件の不等号、更新式と、間違えられる場所が 3 つもあります。配列を全部まわすだけなら、その決まり文句は配列に任せられます。
JavaScript
const works = ["プロフィールサイト", "自己紹介カード", "スキル一覧の表"];
// for-of
for (const work of works) {
console.log(work);
}
// forEach
works.forEach((work) => {
console.log(work);
});結果は同じです。forEach は配列が持っているメソッドで、コールバックを 1 つ受け取ります。先頭から順に要素を取り出し、その要素を引数にしてコールバックを呼んでくれます。ループの仕組みは forEach の側にあるので、こちらは各要素に何をするかだけを書きます。
インデックスが要るときは、第 2 引数で受け取れます。
JavaScript
works.forEach((work, index) => {
console.log(index + " 番目 " + work);
});
// 0 番目 プロフィールサイト
// 1 番目 自己紹介カード
// 2 番目 スキル一覧の表要らなければ書かなくて構いません。空の配列に呼んでもエラーにはならず、コールバックが一度も呼ばれずに終わります。要素数 0 のための if は要りません。
戻り値はいつでも undefined
forEach 自体が返すのは、いつでも undefined です。
JavaScript
const result = works.forEach((work) => work + " 完成");
console.log(result); // undefinedforEach は各要素に何かするための道具であって、変換した新しい配列を作る道具ではありません。結果を集めたいなら、外側に空の配列を用意して push していきます。集め終わった配列は、配列.join("、") のように区切り文字を渡せば 1 本の文字列になります。区切りは要素と要素のあいだにだけ入るので、末尾に余分が残る心配もありません。
break が書けない
for-of との最大の違いがこれです。forEach の中に break を書くと構文エラーになります。
| やりたいこと | for-of | forEach |
|---|---|---|
| 途中で打ち切る | break | 書けない |
| その要素だけ飛ばす | continue | return で代用 |
| インデックスを使う | 自分で数える | 第 2 引数 |
渡しているのは関数なので、その中の break はループを抜ける文として成立しません。ループを止めているのは forEach の側であり、コールバックからは手が届かないのです。途中で打ち切りたくなったら、for-of に書き換えます。
一方、その要素だけ飛ばしたいなら return が使えます。コールバックが終わるだけで、次の要素の処理は続きます。
JavaScript
works.forEach((work) => {
if (work === "下書きメモ") return; // この要素だけ飛ばす
console.log(work);
});この return は continue に相当します。break の代わりにはならない、という点だけ取り違えないでください。
よくある間違い
- 戻り値を受け取ろうとする —
const titles = works.forEach(...)のtitlesは必ずundefinedです。集めたい値は、外に用意した配列へpushします - 丸カッコを付けて渡す —
works.forEach(show())はその場で 1 回だけ実行され、その戻り値が渡ります。渡すのはshowです
要件
- 配列の走査には forEach を使うこと
- 行を集める配列は関数の中で宣言すること
- 空文字列の要素は飛ばし、連番は実際に追加した行数どおりに振ること
- 表示できる作品が 0 件のときは文字列
作品はまだありませんを返すこと
入出力例
listWorks(["プロフィールサイト","自己紹介カード","スキル一覧の表"]) → "1. プロフィールサイト
2. 自己紹介カード
3. スキル一覧の表"
listWorks(["プロフィールサイト","","スキル一覧の表"]) → "1. プロフィールサイト
2. スキル一覧の表"
listWorks(["自己紹介カード"]) → "1. 自己紹介カード"
listWorks([]) → "作品はまだありません"
listWorks(["",""]) → "作品はまだありません"