JavaScript 入門

JavaScript 循環入門

同じタスクを何度も繰り返す必要がある場面を想像してみてください。例えば、1から10まで数える、商品リストを一つずつ処理する、あるいはユーザーが有効な値を入力するまで繰り返し入力を求める、といったタスクです。

もし、繰り返しのたびに同じコードを書き直していたら、効率が悪いだけでなく、ミスも起きやすくなります。そこで登場するのが「ループ(Loop)」です。

プログラミングにおけるループとは、特定の条件が満たされている間(あるいは満たされるまで)、コードの塊を繰り返し実行できるようにする制御フロー文です。ループは、効率的で動的なプログラムを書くための基盤であり、面倒なコピー&ペースト作業なしで反復操作を実行することを可能にします。

1. for文:繰り返しの回数が決まっているとき

for文は、JavaScriptや他の多くのプログラミング言語で最も一般的に使用されるループの一つです。ループを何回繰り返すかが正確にわかっている場合や、明確な開始点と終了点があるシーケンスを走査する場合によく使われます。

1.1 for文の構文と構造

for文は、丸括弧内の3つのオプションのエクスプレッション(式)をセミコロンで区切り、その後にコードブロックを続けます。

for (初期化; 条件; 増分/減分) {
  // 各イテレーションで実行されるコード
}

各パーツを分解してみましょう:

  • 初期化 (initialization): ループ開始時に一度だけ実行されます。通常、ループカウンタ変数を宣言し初期化するために使われます(例:let i = 0;)。
  • 条件 (condition): 各イテレーション(反復)の前に評価されます。条件が true であれば、ループ内のコードブロックが実行されます。false になるとループは終了します。
  • 増分/減分 (increment/decrement): コードブロックの実行が終わるたびに実行されます。通常、ループカウンタ変数を更新するために使われます(例:i++ で増加、i-- で減少)。

1.2 for文の実行フロー

ステップ・バイ・ステップのプロセスは以下の通りです:

  1. 初期化: 初期化式が一度実行される。
  2. 条件チェック: 条件式を評価する。
  3. コードブロックの実行: 条件が true であれば、波括弧 {} 内のコードを実行する。
  4. 増分/減分: 増分/減分式を実行する。
  5. 繰り返し: 条件が false になるまで、ステップ2(条件チェック)に戻る。

1.3 for文のコード例

1.3.1 示例 1:カウントアップ

1から5まで数字を表示したい場合。

console.log("1から5まで数えます:");

for (let i = 1; i <= 5; i++) {
  // 初期化: let i = 1; (i は 1 からスタート)
  // 条件: i <= 5; (i が 5 以下の間はループを継続)
  // 増分: i++; (各イテレーションの後に i を 1 増やす)
  console.log("現在の数字: " + i);
}

// 出力:
// 1から5まで数えます:
// 現在の数字: 1
// 現在の数字: 2
// 現在の数字: 3
// 現在の数字: 4
// 現在の数字: 5

1.3.2 示例 2:カウントダウン

後ろ向きに数えることもできます。

console.log("\n5から1までカウントダウン:");

for (let j = 5; j >= 1; j--) {
  // 初期化: let j = 5; (j は 5 からスタート)
  // 条件: j >= 1; (j が 1 以上の間はループを継続)
  // 減分: j--; (各イテレーションの後に j を 1 減らす)
  console.log("現在のカウント: " + j);
}

1.3.3 示例 3:合計の計算

1から10までの合計を計算してみましょう。

console.log("\n1から10までの合計を計算:");
let sum = 0; // 合計を保存する変数を初期化

for (let k = 1; k <= 10; k++) {
  // 各イテレーションで k の現在値を sum に加算する
  sum = sum + k; // sum += k; と同等
  console.log(`${k} を加算中、現在の合計: ${sum}`);
}

console.log("最終的な合計: " + sum); // 出力: 55

1.4 for文の現実的なユースケース

  • 固定数のアイテム処理: クラスの生徒数が30人と決まっている場合、for文を30回繰り返して各生徒のスコア(平均点の算出など)を処理できます。
  • 視覚的なアニメーションの繰り返し: ゲームでキャラクターを5歩前進させたい場合、キャラクターの位置を5回更新して移動しているように見せることができます。

2. while文:条件が真である限り繰り返す

while文は、もう一つの基本的なループ構造です。回数が決まっている時に使うfor文とは異なり、ある条件が真に保たれている限り、コードブロックを繰り返したい場合に最適です。条件が false になるまでループが続きます。

2.1 while文の構文と構造

while文の構文はfor文よりもシンプルです:

while (条件) {
  // 条件が true である限り実行されるコード
  // 重要:ループ内で条件に関連する変数を更新する必要がある
}

2.2 while文の実行フロー

  1. 条件チェック: 各イテレーションの前に条件式を評価する。
  2. コードブロックの実行: 条件が true であれば、コードを実行する。
  3. 繰り返し: 条件チェックに戻る。
  4. 終了: 条件が false になるとループが終了し、次のコードへ進む。

           注意点: ループ内部で、最終的に条件を false にするステートメントが必要です。条件が永遠に false にならない場合、「無限ループ(Infinite Loop)」となり、プログラムがフリーズしたりクラッシュしたりする原因になります。

2.3 while文のコード例

2.3.1 示例 1:シンプルなカウンタ

回数が決まっている場合はfor文が好ましいですが、while文でも可能です。

console.log("\nwhile文を使って3まで数える:");
let counter = 0; // ループの外で変数を初期化

while (counter < 3) {
  // 条件: counter が 3 未満の間はループ
  console.log("イテレーション回数 " + (counter + 1));
  counter++; // 重要: 最後に条件を false にするためにカウンタを増やす
}

2.3.2 示例 2:ユーザー入力のバリデーションのシミュレーション

これはwhile文の典型的な例です。正しいパスワードが入力されるまで繰り返し入力を求める場面を想定します。

console.log("\nwhile文を使ったパスワード入力シミュレーション:");
let passwordAttempt = "";
const correctPassword = "open123";

// 入力されたパスワードが正解でない限り、ループを継続
while (passwordAttempt !== correctPassword) {
  console.log("パスワードを入力してください:");
  
  // デモ用に、数回のミスを経て正解を入力するようシミュレート
  if (passwordAttempt === "") {
    passwordAttempt = "wrongpass";
    console.log(`(入力シミュレーション: ${passwordAttempt})`);
  } else if (passwordAttempt === "wrongpass") {
    passwordAttempt = "anotherfail";
    console.log(`(入力シミュレーション: ${passwordAttempt})`);
  } else {
    passwordAttempt = correctPassword;
    console.log(`(入力シミュレーション: ${passwordAttempt})`);
  }
}

console.log("パスワード認証成功!ようこそ!");

2.4 while文の現実的なユースケース

  • ゲームループ: 多くのシンプルなゲームにはメインのwhileループがあり、プレイヤーの体力が残っている限り、あるいはゲームオーバーにならない限り走り続けます。
  • データの終端までの読み込み: ファイルやネットワークストリームからデータを処理する際、読み込むデータがある限りwhileループを回し、「ファイル終了」条件を満たした時に終了させます。

3. do...while文:必ず少なくとも一度は実行する

do...while文はwhile文と非常によく似ていますが、大きな違いが一つあります:条件がコードブロックの実行「後」に評価される点です。つまり、最初の条件が truefalse かに関わらず、内部のコードが少なくとも一度は実行されることが保証されます。

3.1 do...while文の構文と構造

do {
  // このコードは少なくとも一度は実行される
  // その後、条件が true である限り繰り返し実行される
} while (条件); // ここにセミコロンが必要!

3.2 do...while文の実行フロー

  1. コードブロックの実行: do ブロック内のコードが一度実行される。
  2. 条件チェック: 実行後に条件式を評価する。
  3. 繰り返し: 条件が true であればステップ1に戻る。
  4. 終了: 条件が false になればループ終了。

3.3 do...while文のコード例

3.3.1 示例 1:条件が最初から偽の場合

while 文と do...while 文の差が最も明確になる例です。

console.log("\ndo...whileループの動作確認:");
let x = 10;

do {
  console.log("この行は一度だけ表示されます。現在のx: " + x);
  x++;
} while (x < 5); // 最初から条件は false だが、一度は実行される

3.3.2 示例 2:メニュー選択のシミュレーション

コマンドラインアプリなどで、メニューを最低一度は表示し、ユーザーが「終了」を選ぶまで繰り返すシナリオです。

console.log("\ndo...while によるメニュー選択シミュレーション:");
let userChoice;
let inputIndex = 0;
let simulatedInputs = ["invalid", "help", "exit"];

do {
  // ユーザー入力ロジックをシミュレート
  if (inputIndex < simulatedInputs.length) {
    userChoice = simulatedInputs[inputIndex];
    inputIndex++;
    console.log(`(模擬入力: '${userChoice}')`);
  } else {
    userChoice = "exit";
  }

  if (userChoice === "exit") {
    console.log("プログラムを終了します。");
  } else if (userChoice === "help") {
    console.log("ヘルプ情報を表示中...");
  } else {
    console.log("無効な選択です。リトライしてください。");
  }
} while (userChoice !== "exit");

3.4 do...while文の現実的なユースケース

  • メニュー駆動型プログラム: ユーザーに選択肢を提示し、「終了」が選ばれるまでループさせる場合、メニューは最低一度は表示される必要があります。
  • セットアップウィザード: インストール時の「ようこそ」画面やライセンス同意画面などは必ず一度は表示される必要があり、その後ユーザーの操作に応じて次へ進むか繰り返すかを決定します。

4. 適切なループの選択

どのタイプのループを使うべきかを見極める基準は以下の通りです:

  • for文: 繰り返しの回数が事前にわかっている、または明確な開始・終了・ステップ幅がある場合(例:配列の走査、固定範囲のカウント)。
  • while文: 繰り返しの回数が不明だが、ある条件が真である間だけ続けたい場合。条件は実行前にチェックされる。
  • do...while文: ループの中身を最低一回は実行する必要があり、その後条件に応じて繰り返すかを決めたい場合。条件は実行後にチェックされる。