JavaScriptでアプリケーションを開発する際、配列のデータ処理や数値計算などで「繰り返し処理(ループ)」は欠かせない要素です。
大量のデータを処理する中で、特定の条件に合致するデータだけを除外したり、特定のステップをスキップしたりしたい場面は頻繁に発生します。
このような制御をスマートに実現するのが、今回詳しく解説するcontinue文です。
プログラミング初心者の方はもちろん、中級者の方にとっても、ループ制御を正しく理解することは「読みやすく、バグの少ないコード」を書くための第一歩となります。
本記事では、JavaScriptにおけるループスキップの基本から、実務で役立つ応用テクニック、さらには注意点までを網羅的にご紹介します。
JavaScriptのループ制御におけるcontinue文の役割
JavaScriptには、ループの動きを制御するための特別なキーワードがいくつか用意されています。
その中でもcontinue文は、現在実行中の反復処理(イテレーション)をその時点で終了させ、次の反復処理へと即座に移行させる役割を持っています。
例えば、1から10まで数字を数えるループの中で、5の時だけ処理を飛ばして6に進むといった制御が可能です。
この命令が実行されると、ループブロック内のcontinue以降に記述されたコードは無視されます。
しかし、ループ自体が終了するわけではなく、カウンタ変数の更新などを経て、再びループの先頭から処理が継続されるのが特徴です。
複雑な条件分岐が重なる処理において、特定の条件を除外するために活用することで、ソースコードの可読性を劇的に向上させることができます。
break文との明確な違い
ループ制御において、continue文とよく混同されるのがbreak文です。
両者の違いを正確に理解しておくことは、意図しない無限ループやロジックミスを防ぐために非常に重要です。
以下の表で、その動作の違いを比較してみましょう。
| 命令 | 動作内容 | ループの継続 |
|---|---|---|
continue | 現在の回だけをスキップして、次の回へ進む | 継続する |
break | ループ処理そのものを強制的に終了する | 終了する |
このように、continueは「部分的なスキップ」を目的とし、breakは「完全な脱出」を目的としています。
例えば、エラーが発生した瞬間にすべての処理を止めたい場合はbreakを使用し、不正なデータだけを無視して残りの処理を続けたい場合はcontinueを選択します。
continue文の基本的な使い方と記述例
まずは、最も一般的なfor文におけるcontinue文の使い方を確認していきましょう。
基本的な構文は非常にシンプルで、通常はif文による条件判定とセットで使用されます。
// continue文の基本構文
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) {
// iが偶数の場合、これ以降の処理をスキップして次のiへ
continue;
}
console.log(i + "は奇数です。");
}
1は奇数です。
3は奇数です。
5は奇数です。
7は奇数です。
9は奇数です。
このプログラムでは、変数iが偶数のときにcontinueが実行されます。
その結果、偶数のときだけconsole.logが実行されず、奇数のときだけ出力が行われる仕組みになっています。
for文での活用シーン:特定条件の除外
実務的な例として、ユーザーリストの中から「管理者以外」のユーザーに対してのみメッセージを表示する処理を考えてみましょう。
const users = [
{ name: "田中", role: "admin" },
{ name: "佐藤", role: "user" },
{ name: "鈴木", role: "user" },
{ name: "高橋", role: "guest" }
];
for (let i = 0; i < users.length; i++) {
// 管理者は処理をスキップする
if (users[i].role === "admin") {
continue;
}
console.log(users[i].name + "さんに通知を送信しました。");
}
佐藤さんに通知を送信しました。
鈴木さんに通知を送信しました。
高橋さんに通知を送信しました。
このように、特定のデータを除外して処理を進める「ガード句」のような役割としてcontinueを活用するのが一般的です。
while文で使用する際の注意点
while文やdo...while文でcontinue文を使用する場合には、重大な注意点があります。
for文とは異なり、while文ではカウンタ変数の更新(増分処理)をループ内の最後に記述することが多いため、continueの配置によっては無限ループに陥る危険性があります。
// 注意が必要なwhile文の例
let i = 0;
while (i < 5) {
if (i === 2) {
// ここでcontinueすると、i++が実行されず、iは永遠に2のまま
continue;
}
console.log(i);
i++;
}
上記のコードを実行すると、iが2になった瞬間にcontinueが実行され、それ以降のi++が永遠に呼ばれなくなります。
その結果、条件式i < 5が常に真となり、ブラウザのフリーズやクラッシュを引き起こす無限ループが発生します。
while文でcontinueを使う際は、スキップする前に必ず更新処理を行うか、カウンタの更新が確実に行われる仕組みを検討してください。
配列操作でのループスキップ手法
JavaScriptでは従来のfor文以外にも、配列を扱うための便利なループ構文がいくつか存在します。
それぞれの構文で、どのようにスキップ処理を実現するのかを見ていきましょう。
for…of文での利用
ES6から導入されたfor...of文は、配列の要素を直接取り出すことができるため、非常に読みやすいコードが書けます。
この構文の中でも、continue文はfor文と同様に機能します。
const numbers = [10, -5, 20, -1, 30];
for (const num of numbers) {
// 負の数はスキップして処理を継続
if (num < 0) {
continue;
}
console.log("正の数:" + num);
}
for...of文はカウンタ変数の管理が不要なため、先述したwhile文のような無限ループのリスクも低く、モダンなJavaScript開発において推奨される書き方の一つです。
forEachメソッドでの代替手段
配列のメソッドであるforEachを使用している場合、実はcontinue文を使用することができません。
forEachの中でcontinueを記述すると、構文エラー(SyntaxError)が発生してしまいます。
forEachで「現在の処理をスキップして次に進む」動きを実現したい場合は、関数のreturn命令を使用します。
const data = ["apple", "banana", "", "orange"];
data.forEach((item) => {
if (item === "") {
// continueの代わりにreturnを使う
return;
}
console.log("フルーツ名:" + item);
});
forEachに渡しているのはコールバック関数であるため、returnを呼び出すことでその回の関数実行だけを終了させ、次の要素の処理に移ることができるのです。
ただし、forEachではループ自体の中断(break)もできないため、複雑なループ制御が必要な場合はfor...of文の使用を検討しましょう。
ネストされたループでのcontinue文(ラベル付き文)
二重ループ、三重ループのようにループが入れ子(ネスト)になっている構造では、continueの影響範囲をより細かく制御したい場合があります。
デフォルトでは、continue文は最も内側のループのみをスキップ対象とします。
しかし、「外側のループをスキップさせたい」という場合には、「ラベル付き文」という機能を利用します。
// 外側のループに「outerLoop」という名前を付ける
outerLoop: for (let i = 1; i <= 3; i++) {
for (let j = 1; j <= 3; j++) {
if (i === 2 && j === 2) {
// 外側のループをスキップ対象にする
continue outerLoop;
}
console.log(`i=${i}, j=${j}`);
}
}
i=1, j=1
i=1, j=2
i=1, j=3
i=2, j=1
i=3, j=1
i=3, j=2
i=3, j=3
上記の実行結果を見ると、i=2, j=2のタイミングで外側のループがスキップされ、i=2, j=3の処理が行われずにi=3へ移動していることがわかります。
ラベル付き文は強力ですが、多用するとコードの構造が追いづらくなるため、どうしても必要な場合のみ限定的に使用するのがベストプラクティスです。
continue文を使うべき場面とコードを綺麗に保つコツ
continue文を使いこなすことで、コードのネスト(階層)を浅くし、読みやすく保つことができます。
この手法は「ガード句」と呼ばれ、条件を満たさないものを最初に排除する考え方です。
ネストが深いコード(改善前)
for (const item of items) {
if (item.isActive) {
if (item.hasPermission) {
if (item.value > 100) {
// ここでようやく本来やりたい処理を行う
process(item);
}
}
}
}
このようにif文が重なると、右側にどんどんコードが寄ってしまい、構造の把握が難しくなります。
continueを使ったコード(改善後)
for (const item of items) {
// 逆の条件でスキップしていく
if (!item.isActive) continue;
if (!item.hasPermission) continue;
if (item.value <= 100) continue;
// 本来やりたいメインの処理
process(item);
}
このようにcontinueを使って例外的なパターンを先に弾いておくことで、メインの処理をインデントを下げずに記述できるようになります。
これは「Happy Path(正常系)」と呼ばれる、最も一般的な処理の流れを際立たせる効果があります。
パフォーマンスとモダンな代替手法
近年のJavaScript開発(特に2026年時点のようなモダンな環境)では、命令的なループ処理よりも、関数型プログラミングのスタイルが好まれる傾向にあります。
ループ内でcontinueを使ってデータをフィルタリングする代わりに、配列のfilterメソッドを使う方法も検討すべきです。
const sourceArray = [1, 2, 3, 4, 5, 6];
// continueを使わずに、filterで必要なものだけ抽出する
const processedData = sourceArray
.filter(num => num % 2 === 0) // 偶数のみ抽出
.map(num => num * 10); // 抽出したものを10倍にする
console.log(processedData);
filterメソッドを使用すると、「何をしたいのか」という意図がより明確に伝わるコードになります。
パフォーマンス面では、超巨大な配列(数百万件など)を扱う場合、従来のfor文とcontinueの組み合わせの方が高速な場合もあります。
しかし、ほとんどの一般的なWebアプリケーション開発においては、保守性の高いfilterやmapといった配列メソッドの方が適しています。
状況に応じて、パフォーマンス重視のcontinueか、可読性重視の配列メソッドかを使い分けるバランス感覚が求められます。
まとめ
JavaScriptにおけるcontinue文は、ループ処理の柔軟性を高め、コードを簡潔にするための強力な武器です。
現在の反復をスキップして次へ進むというシンプルな動作ですが、break文との違いやwhile文での無限ループリスクなど、押さえておくべきポイントは多岐にわたります。
特に、ガード句として活用することでコードのネストを浅く保つテクニックは、プロフェッショナルな現場でも広く活用されています。
また、forEachではreturnで代用する必要があることや、より宣言的なfilterメソッドの活用など、代替手段もセットで覚えておくと開発の幅が広がります。
今回学んだループ制御のコツを活かして、より効率的で美しいJavaScriptのコードを追求してみてください。
