【JavaScript】forEachとcontinueの使い方を初心者向けにわかりやすく解説
はじめに
JavaScriptで配列を扱う際、繰り返し処理を行うメソッドとしてforEachがよく使われます。
しかし、従来のfor
やwhile
などのループ構文のように、continue
やbreak
がそのまま使えないところが初心者の皆さんにとっては少しわかりにくいポイントかもしれません。
そこでこの記事では、**「javascript foreach continue」**というキーワードが示すとおり、forEachとcontinueの関係性を丁寧に解説します。
「なぜcontinueが使えないの?」「どうやって特定の要素だけスキップできる?」といった疑問を、具体的なコード例を交えながら一つひとつクリアにしていきます。
また、実務での活用シーンも踏まえ、どのように書くと可読性や保守性が向上するかについても触れます。
初心者の方でも理解しやすい言葉で解説しますので、これからJavaScriptのループ処理を学ぶ方はぜひ参考にしてみてください。
この記事を読むとわかること
- JavaScriptにおけるforEachの基礎的な使い方
- forEachとcontinueが直接組み合わせられない理由
- スキップ処理を行うための具体的なサンプルコード
- 実務でどのような場面で有効か
- 他のループ構文との違いと選択のポイント
JavaScriptのループ処理の基本
JavaScriptには、配列やオブジェクトなどのデータを繰り返し処理するさまざまな方法があります。
もっとも基本的なものとして、for
構文やwhile
構文が挙げられます。
配列の要素を順番に取り出して処理を行いたいとき、これらのループ処理を組み合わせて使えば多くの場合は事足ります。
ただし、コードが複雑になりがちな場面では、可読性や保守性を高めるために、配列のメソッドであるforEach
が活用されることがよくあります。
forEach
を使うと、for
構文よりも見た目がすっきりすることが多く、またコールバック関数を使ってわかりやすく処理を記述できます。
一方で、for
などに慣れていると、「繰り返しの途中で何かをスキップしたい」というときに、自然とcontinue
やbreak
を思い浮かべるのではないでしょうか。
しかし、forEach
自体はcontinue
やbreak
をサポートしていません。
これは構造的な理由があるため、別の方法でスキップやループ抜けといった動きを実装する必要があります。
forEachとは何か?
forEachは、配列オブジェクトのメソッドの一つです。
配列の各要素に対して、順番にコールバック関数を実行してくれます。
たとえば次のようなコードがあるとします。
const numbers = [1, 2, 3, 4, 5]; numbers.forEach((num) => { console.log(num); });
この場合、配列numbers
に含まれるすべての要素が順番にnum
として取り出され、console.log(num)
が呼び出されます。
結果として、1から5までが順番にコンソールに出力されるわけです。
コールバック関数は、3つの引数を受け取ることができます。
- 配列の現在の要素
- 現在の要素のインデックス
- 元の配列オブジェクト
これを活用することで、ただ値を処理するだけでなく、インデックスを見て制御フローを変えたり、もとの配列を参照して別の加工をしたりできます。
しかし、後述するようにforEach
では直接continue
やbreak
を使ったループ制御が行えない点には注意が必要です。
forEachとcontinueの関係
一般的に、for
やwhile
構文の中でcontinue
を使うと、ループのその時点の処理をスキップし、次の反復に進むことができます。
たとえば次のようなコードであれば、値が偶数のときだけスキップするという処理が直感的に書けるでしょう。
for (let i = 0; i < 5; i++) { if (i % 2 === 0) { continue; } console.log("奇数:", i); }
この例では、i
が偶数(0, 2, 4
)のときにはcontinue
でスキップが発生し、奇数の1, 3
だけが出力される仕組みです。
一方、同じ処理をforEach
で書こうとすると、次のようなコードを思い浮かべる方もいるかもしれません。
const numbers = [0, 1, 2, 3, 4]; numbers.forEach((num) => { if (num % 2 === 0) { continue; // エラーになる } console.log("奇数:", num); });
ところが、これではエラーが発生してしまい、実行が止まります。
forEach
は内部的に関数呼び出しによって要素を処理しているため、JavaScript言語としてのcontinue
文がそのまま認識されないのです。
この仕様を理解していないと、「どうしてcontinueが効かないんだろう?」と戸惑ってしまうでしょう。
しかし、forEach
では別の手段を使ってスキップのような動きを実現できます。
それを次の見出しで詳しく紹介します。
forEachでループをスキップする方法
forEach
のループをスキップするには、早期リターンという考え方が有効です。
continue
が使えなくても、コールバック関数の中でreturn
を行うことで、その回の処理をすぐに終了できます。
たとえば、先ほどの例をforEach
で書き直すと以下のようになります。
const numbers = [0, 1, 2, 3, 4]; numbers.forEach((num) => { if (num % 2 === 0) { // ここでコールバック関数を終了する(return) return; } console.log("奇数:", num); });
return
によってその回の処理を打ち切るため、num
が偶数の場合は後続のconsole.log
が実行されません。
結果的に、いわゆる「スキップ」と同じ動きになります。
このパターンを理解するだけでも、forEach
でcontinueを使おうとしたときの大半のケースに対応できるでしょう。
ただし、forEach
にはループ自体を完全に終了させる手段が用意されていません。
return
はあくまでそのコールバック関数の処理を終わらせるだけで、break
のようにループ全体を抜けるわけではありません。
もし途中でループ自体を停止したい場合は、forEach
ではなく、後述するfor...of
やfor
など別の構文の利用を検討してください。
if文を使ったスキップの具体例
実務では、ある条件のときは処理を行わずに次の要素を処理したい、といった場面がしばしばあります。
たとえば、メールアドレスのリストを処理していて、一時的に無効になっているアドレスだけをスキップしたいようなケースを考えます。
const emailList = [ { address: "example1@example.com", active: true }, { address: "example2@example.com", active: false }, { address: "example3@example.com", active: true }, ]; emailList.forEach((email) => { if (!email.active) { // activeがfalseならスキップ return; } // スキップされなければ、本来の処理を実行 console.log("送信可能なアドレス:", email.address); });
ここではactive
がfalse
である要素をスキップし、それ以外の要素だけに対して処理を実行しています。
continue
こそ使っていませんが、意図した結果を得られるはずです。
実務での活用シーン
システム開発やWebアプリケーション開発では、配列の要素をまとめて処理するときがよくあります。
たとえば、ユーザーから受け取ったデータを逐次チェックして、不備があれば別の処理をする、またはスキップするといったケースが想定されるでしょう。
このようなとき、forEach
でスキップ動作を実現するには「特定の条件を満たす場合はreturn
して、それ以上の処理を行わない」という書き方が最もシンプルです。
一方で、処理を進めていくうちに「不備のあるデータが多すぎるときにはループ自体を止めたい」といった要件が出てくるケースも考えられます。
こうした場面でforEach
を使うと、前述のとおりbreak
相当の動きを簡単には実装できないため、別のループ構文を選んだほうが可読性が高くなるでしょう。
たとえば、大きな配列のデータを取り扱う業務システムで、途中で特定の閾値を超えたエラーが出たら処理を一旦中断する、といった要件を実現するにはfor
やfor...of
の方が書きやすいかもしれません。
実務では、こうした要件と可読性のバランスを考慮して、forEach
を活用するか、それとも別のループ手段を選ぶかを決めることがポイントです。
代替構文:for-of や for など
上記で解説したように、forEach
ではコールバック関数の「早期リターン」はできても、ループ全体を抜けるbreak
は実行できません。
そのため、途中でループを完全に終了する必要がある場合は、for
や for...of
などの構文が利用候補に挙がります。
for-of を使った例
const numbers = [10, 20, 30, 40, 50]; for (const num of numbers) { if (num === 30) { break; // 30が見つかったらループを終了 } console.log("処理対象:", num); }
このコードでは、numbers
という配列をfor...of
でループし、num
が30に等しいときにループを終了します。
forEach
では難しかった「途中で抜ける」動きをスッキリ書けるのが利点です。
一方、配列の要素がすべて処理される前にループを抜けるため、他の要素が処理されない点には注意が必要です。
通常のfor構文での例
const numbers = [10, 20, 30, 40, 50]; for (let i = 0; i < numbers.length; i++) { if (numbers[i] === 30) { break; } console.log("処理対象:", numbers[i]); }
こちらは昔ながらのfor
構文を使った例です。
i
を手動でインクリメントしながらループを回すので、配列の長さやインデックスを明示的に管理します。
break
やcontinue
を直接使える点で、必要に応じたフロー制御がしやすいのが特徴です。
使い分けとしては、「途中でループを脱出する必要がないならforEach
」「途中で脱出したい可能性があるならfor
やfor-of
」といった分け方が一例として考えられます。
実務ではチームのコーディング規約や、他のメンバーが理解しやすいスタイルなども合わせて検討しながら選ぶとよいでしょう。
例外処理との組み合わせ
スキップと同時にエラー処理を考慮しなければならない場面もあります。
たとえば、配列の要素を処理していて、データ形式が不正なものが混じっているかもしれないケースです。
このようなとき、単にスキップするだけでなく、状況に応じてエラーを投げたりログを記録したりすることが重要になります。
forEach
の場合は次のように書けます。
const dataList = [ { value: 100 }, { value: "abc" }, { value: 300 }, ]; dataList.forEach((item, index) => { if (typeof item.value !== "number") { console.error("数値ではありません:", item, "インデックス:", index); return; // 処理をスキップ } // 数値の場合の処理 console.log("数値:", item.value); });
ここで使っているのは、あくまで「不正なデータを見つけても、単にスキップする」という実装です。
本当に重大な問題の場合は、スキップではなくthrow new Error("エラー内容")
のように例外を投げて後続の処理を停止させたほうがよいケースもあるでしょう。
しかしforEach
では「その場で例外を投げると、以降の要素処理は行われない」ことになるため、本当にそれでよいのかを事前に検討しておく必要があります。
実務上は、各要素の検証が終わった後でまとめて結果を確認する方法や、問題のある要素だけ別の配列に抽出するといった方法もあります。
アプリケーションの要件に合わせて柔軟に対応するとよいでしょう。
ループ全体を途中で停止するか、スキップにとどめるかは要件によって異なります。
運用上の要件や、エラーがあったときにどのような対処が必要かによって、スキップか強制停止かを明確に決定しておきましょう。
continue代わりのパターンまとめ
forEach
内でcontinue
を使いたいときは、早期リターンを利用するのが一般的なパターンです。
具体的には、下記のような流れになります。
- 条件を満たすかチェックする
- 条件を満たす場合は
return
でコールバック関数を抜ける - 満たさない場合のみ本来の処理を実行する
たとえば次のようなコードです。
array.forEach((item) => { if (/* スキップしたい条件 */) { return; } // スキップしない場合の処理 });
こうすると、従来のループ構文におけるcontinue
と同様の効果が得られます。
もちろん、ループ全体を終了させたいわけではない場合にのみ使う方法です。
もし途中で完全に処理を打ち切りたいのなら、forEach
は避けて別の構文を使うという選択が適切でしょう。
実務視点で考えるメリットとデメリット
メリット
- コードがすっきりしやすい
- コールバック関数内に処理がまとまる
- インデックスや元配列も受け取れる
デメリット
continue
やbreak
が使えず、スキップやループ中断には工夫が必要- 大きな配列を扱う場合、性能面で
for
との違いを認識しておく必要がある - ループ内のロジックが複雑になると、かえって読みづらくなる可能性がある
実際には、配列の要素数が膨大だったり、途中で抜けたい要件が多いといった状況では、従来のfor
構文やfor...of
構文の方が適している場合もあります。
最終的には「自分やチームが読みやすく、要件を満たせる書き方を選ぶ」ことが一番大切なポイントになります。
よくある疑問と解消策
初心者の皆さんがJavaScriptの繰り返し処理について学ぶ際、forEach
の動き方やcontinue
が使えない理由でつまずくことが多いように思います。
ここでは、よくある疑問をいくつか簡単にまとめてみます。
配列の途中で処理を完全に終了したい
forEach
ではなく、for
またはfor...of
構文を使う。
break
を利用してループから抜けるのが手早い。
エラーが発生したら処理を全部止めたい
例外を投げるか、早期リターンを使うかは要件次第。
ただしforEach
では、コールバック内で例外が投げられると残りの要素は処理されないので注意。
インデックスを直接操作したい
forEach
の第2引数としてインデックスを受け取ることは可能。
しかし、「次の要素だけをスキップ」など細かな制御が必要なら、通常のfor
構文などを使うとわかりやすい。
まとめ
JavaScriptのforEach
は、簡潔な書き方で配列の要素を処理できる便利なメソッドです。
一方で、伝統的なfor
やwhile
と違ってcontinue
やbreak
がそのまま使えず、スキップやループの中断には工夫が求められます。
結論としては、**「forEach内でcontinueに相当する動きを実現したいときは早期リターンを使う」**というのが基本的な対処法です。
途中でループ自体を終了したいなら、forEach
ではなくfor...of
やfor
を選ぶことで、break
を使った構文が書けるようになります。
実務では、「途中で中断する必要があるか」「特定の要素だけスキップしたいだけなのか」などの要件を明確にし、最適なループ構文を選ぶことが大切です。
ぜひ今回の記事を参考にしながら、実際のコードでどのように書くと読みやすく、保守しやすいかを考えてみてください。
そうすれば、JavaScriptのループ処理をより自在に操れるようになるのではないでしょうか。