【Javascript】 whlie文 (ループ) – プログラミング入門

while文は、条件を満たす限りループし続けるものです。for文を似ていますが、いくつか違う内容があります。

書き方

ifやfor等と同様に、whileを使用します。

let x = 1;
while (x < 10) {
    x *= 2;
    console.log(x);
}
2
4
8
16

まるでif文のような書き方ですね。while (条件) {実行内容}となっています。

異なるのは条件を満たす限りループするという点で、初回を含めループのたびに条件が判定されます。

for文と違うのは、forにある初期化処理がないのと、ループ後の後処理も無い、というところです。

do-while

もう一つ、dowhileを使った書き方があります。

let x = 1;
do {
    x *= 2;
    console.log(x);
} while(x < 10)
2
4
8
16

同じようにループするという点は同じですが、初回だけ判定せず必ず実行します。

whileでは初回も判定したので、その違いです。

let x = 100;
do {
    x *= 2;
} while(x < 10)
console.log(x);
200

初回は無条件で実行し、その後x < 10の判定を行ってループするか判断しています。

forとwhileの使い分け

for文は、配列のインデックスなどが関わってくる場合によく利用します。つまり、回数をカウントして回したい場合によく利用します。

while文は、カウント数とは関係ない条件が関わってくるときによく利用します。つまり、ループ回数がわからない場合に使用します。

両方関わってくる場合、for文にした上でbreakを書くことが多いです。

while文が適している例

ループ回数が決まらない場合

例えば、入力が正しいかどうかの例を考えてみます。

入力が正しいかどうかということは、何回入力をチェックし、入力待ち状態にしたらよいかが決まらない、ということです。

let inputText = "";

while(inputText.length >= 10) {
    // 入力をさせてinputTextに代入する処理
}

上の例では、1000回入力させても、文字の長さが10文字以上になるとは限りません。また、正しく入力されたのに強制的に1000回入力させる、というのもおかしいですよね。

このように、回数が定まらない場合によく使用します。

配列の要素数が変わる場合

これは特殊な例で発展的な内容ですが、ループ中に要素数が変わると、しばしばうまく行かなくなります。

let a = [1, 2, 3];
for (let i = 0; i < a.length; i++) {
    a.pop(); // 配列の最後尾を削除
}
console.log(a);

上の例では、ループ中に配列の要素が減っています。想定としては、中身を全部削除したいというところでしょうか。3回popしてほしいところです。

しかし、結果はそうは行きません。

result
[ 1 ]

なんと要素が残りました。なぜかというと、2回削除した時点で、a.length1になっており、3回目のループに入らないためです。

つまり、ループ中に要素数が変わる場合は.lengthを判定に使うfor文を書くべきではない、ということです。

全削除でなくても、インデックスがずれてうまく行かないというのはよくあることです。

今回の例だと、ループ回数を指定するのではなく、全部削除されたかどうか (つまり要素が0個かどうか) を見るべきです。

let a = [1, 2, 3];
while (a.length > 0) {
    a.pop(); // 配列の最後尾を削除
}

これなら全部削除できます!

for (;a.length > 0;) { a.pop(); }でも確かに動きますが、冗長です。while文の方が余分な文字がなく、スッキリします。

無限ループ

時々、while文を利用した無限ループを書きます。

while(1) {
    console.log("無限ループ");
}

for (;;) {/*...*/}という無限ループの書き方もありますが、whileの方が簡潔です。

通常はforの方が速いですが、C言語などではコンパイル時に最適化されるので差はありません。

無限ループをするといつまでも終わらなくなるので、何かしらの条件でbreakさせる必要があります。

while(1) {
    if (/*...*/) {
        break;
    }

    /* ... */

    if (/*...*/) {

    } else {
        break;
    }
}

しばしば、ループ中断条件が複雑な場合で、位置もバラバラになるような場合に用いることがあります。

しかし、無限ループする危険性があるため、できるだけ書かないで済むようにしましょう。

まとめ

while文はforと似ていますが、初期化処理がない、後処理もないというところが異なります。

出番はforと比べると少ないですが、使うときは必ずやってきます。こちらもしっかり把握しましょう!

while thumb

役に立ったらシェアしよう!