【JavaScript】forEachとcontinueの使い方を初心者向けにわかりやすく解説

はじめに

JavaScriptで配列を扱う際、繰り返し処理を行うメソッドとしてforEachがよく使われます。
しかし、従来のforwhileなどのループ構文のように、continuebreakがそのまま使えないところが初心者の皆さんにとっては少しわかりにくいポイントかもしれません。

そこでこの記事では、**「javascript foreach continue」**というキーワードが示すとおり、forEachとcontinueの関係性を丁寧に解説します。
「なぜcontinueが使えないの?」「どうやって特定の要素だけスキップできる?」といった疑問を、具体的なコード例を交えながら一つひとつクリアにしていきます。

また、実務での活用シーンも踏まえ、どのように書くと可読性や保守性が向上するかについても触れます。
初心者の方でも理解しやすい言葉で解説しますので、これからJavaScriptのループ処理を学ぶ方はぜひ参考にしてみてください。

この記事を読むとわかること

  • JavaScriptにおけるforEachの基礎的な使い方
  • forEachcontinueが直接組み合わせられない理由
  • スキップ処理を行うための具体的なサンプルコード
  • 実務でどのような場面で有効か
  • 他のループ構文との違いと選択のポイント

JavaScriptのループ処理の基本

JavaScriptには、配列やオブジェクトなどのデータを繰り返し処理するさまざまな方法があります。
もっとも基本的なものとして、for構文やwhile構文が挙げられます。
配列の要素を順番に取り出して処理を行いたいとき、これらのループ処理を組み合わせて使えば多くの場合は事足ります。

ただし、コードが複雑になりがちな場面では、可読性保守性を高めるために、配列のメソッドであるforEachが活用されることがよくあります。
forEachを使うと、for構文よりも見た目がすっきりすることが多く、またコールバック関数を使ってわかりやすく処理を記述できます。

一方で、forなどに慣れていると、「繰り返しの途中で何かをスキップしたい」というときに、自然とcontinuebreakを思い浮かべるのではないでしょうか。
しかし、forEach自体はcontinuebreakをサポートしていません。
これは構造的な理由があるため、別の方法でスキップやループ抜けといった動きを実装する必要があります。

forEachとは何か?

forEachは、配列オブジェクトのメソッドの一つです。
配列の各要素に対して、順番にコールバック関数を実行してくれます。
たとえば次のようなコードがあるとします。

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

numbers.forEach((num) => {
  console.log(num);
});

この場合、配列numbersに含まれるすべての要素が順番にnumとして取り出され、console.log(num)が呼び出されます。
結果として、1から5までが順番にコンソールに出力されるわけです。

コールバック関数は、3つの引数を受け取ることができます。

  1. 配列の現在の要素
  2. 現在の要素のインデックス
  3. 元の配列オブジェクト

これを活用することで、ただ値を処理するだけでなく、インデックスを見て制御フローを変えたり、もとの配列を参照して別の加工をしたりできます。
しかし、後述するようにforEachでは直接continuebreakを使ったループ制御が行えない点には注意が必要です。

forEachとcontinueの関係

一般的に、forwhile構文の中で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...offorなど別の構文の利用を検討してください。

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);
});

ここではactivefalseである要素をスキップし、それ以外の要素だけに対して処理を実行しています。
continueこそ使っていませんが、意図した結果を得られるはずです。

実務での活用シーン

システム開発やWebアプリケーション開発では、配列の要素をまとめて処理するときがよくあります。
たとえば、ユーザーから受け取ったデータを逐次チェックして、不備があれば別の処理をする、またはスキップするといったケースが想定されるでしょう。
このようなとき、forEachでスキップ動作を実現するには「特定の条件を満たす場合はreturnして、それ以上の処理を行わない」という書き方が最もシンプルです。

一方で、処理を進めていくうちに「不備のあるデータが多すぎるときにはループ自体を止めたい」といった要件が出てくるケースも考えられます。
こうした場面でforEachを使うと、前述のとおりbreak相当の動きを簡単には実装できないため、別のループ構文を選んだほうが可読性が高くなるでしょう。

たとえば、大きな配列のデータを取り扱う業務システムで、途中で特定の閾値を超えたエラーが出たら処理を一旦中断する、といった要件を実現するにはforfor...ofの方が書きやすいかもしれません。
実務では、こうした要件と可読性のバランスを考慮して、forEachを活用するか、それとも別のループ手段を選ぶかを決めることがポイントです。

代替構文:for-of や for など

上記で解説したように、forEachではコールバック関数の「早期リターン」はできても、ループ全体を抜けるbreakは実行できません。
そのため、途中でループを完全に終了する必要がある場合は、forfor...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を手動でインクリメントしながらループを回すので、配列の長さやインデックスを明示的に管理します。
breakcontinueを直接使える点で、必要に応じたフロー制御がしやすいのが特徴です。

使い分けとしては、「途中でループを脱出する必要がないならforEach」「途中で脱出したい可能性があるならforfor-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を使いたいときは、早期リターンを利用するのが一般的なパターンです。
具体的には、下記のような流れになります。

  1. 条件を満たすかチェックする
  2. 条件を満たす場合はreturnでコールバック関数を抜ける
  3. 満たさない場合のみ本来の処理を実行する

たとえば次のようなコードです。

array.forEach((item) => {
  if (/* スキップしたい条件 */) {
    return;
  }
  // スキップしない場合の処理
});

こうすると、従来のループ構文におけるcontinueと同様の効果が得られます。
もちろん、ループ全体を終了させたいわけではない場合にのみ使う方法です。
もし途中で完全に処理を打ち切りたいのなら、forEachは避けて別の構文を使うという選択が適切でしょう。

実務視点で考えるメリットとデメリット

メリット

  • コードがすっきりしやすい
  • コールバック関数内に処理がまとまる
  • インデックスや元配列も受け取れる

デメリット

  • continuebreakが使えず、スキップやループ中断には工夫が必要
  • 大きな配列を扱う場合、性能面でforとの違いを認識しておく必要がある
  • ループ内のロジックが複雑になると、かえって読みづらくなる可能性がある

実際には、配列の要素数が膨大だったり、途中で抜けたい要件が多いといった状況では、従来のfor構文やfor...of構文の方が適している場合もあります。
最終的には「自分やチームが読みやすく、要件を満たせる書き方を選ぶ」ことが一番大切なポイントになります。

よくある疑問と解消策

初心者の皆さんがJavaScriptの繰り返し処理について学ぶ際、forEachの動き方やcontinueが使えない理由でつまずくことが多いように思います。
ここでは、よくある疑問をいくつか簡単にまとめてみます。

配列の途中で処理を完全に終了したい

forEachではなく、forまたはfor...of構文を使う。
breakを利用してループから抜けるのが手早い。

エラーが発生したら処理を全部止めたい

例外を投げるか、早期リターンを使うかは要件次第。
ただしforEachでは、コールバック内で例外が投げられると残りの要素は処理されないので注意。

インデックスを直接操作したい

forEachの第2引数としてインデックスを受け取ることは可能。
しかし、「次の要素だけをスキップ」など細かな制御が必要なら、通常のfor構文などを使うとわかりやすい。

まとめ

JavaScriptのforEachは、簡潔な書き方で配列の要素を処理できる便利なメソッドです。
一方で、伝統的なforwhileと違ってcontinuebreakがそのまま使えず、スキップやループの中断には工夫が求められます。

結論としては、**「forEach内でcontinueに相当する動きを実現したいときは早期リターンを使う」**というのが基本的な対処法です。
途中でループ自体を終了したいなら、forEachではなくfor...offorを選ぶことで、breakを使った構文が書けるようになります。

実務では、「途中で中断する必要があるか」「特定の要素だけスキップしたいだけなのか」などの要件を明確にし、最適なループ構文を選ぶことが大切です。
ぜひ今回の記事を参考にしながら、実際のコードでどのように書くと読みやすく、保守しやすいかを考えてみてください。
そうすれば、JavaScriptのループ処理をより自在に操れるようになるのではないでしょうか。

JavaScriptをマスターしよう

この記事で学んだJavaScriptの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。