現役プログラマーによるJavaScript奮闘記13!~その他いろいろな文編~

前回は繰り返し文について書きました。

今回はその繰り返し文で使えるテクニックみたいな物を書いていきます。
繰り返しって打つのがちょっと面倒なので、これ以降ループって書きます。

■break文

一単語なのに文!
ループの中で「○○だったらループ処理を終わらせる」というときにこれを使います。
while(条件式)の条件式をループ中に書くみたいなイメージですかね。

ループの中でbreakが実行されるとそのタイミングで強制的にそのループを抜けます。

前回同様1~100を出力する場合、while文だとこう書きました。


var count = 1;
while(count <= 100) {
  document.write(count);
  count++;
}

これをbreakを使うとこんな感じになります。

var count = 1;
while(true) {
 document.write(count);
 count++;
 if(count > 100){
   break;
 }
}

>while(true) {
なのでこれは無限ループです。こっわ!
でも

> if(count > 100){
> break;
> }
があるので、countが100より大きくなったタイミングでbreak文が実行され、このループが終了します。

以前switch-case文でもbreakを書きましょうと書きましたが、どちらも同じbreakです。
breakは実行されている文を強制的に終了させるという文になります。

■continue文

先ほどのbreakはループを強制終了させるでした。
このcontinue文は、実行されたタイミングでそのループの先頭に戻ります。
ぱっと聞いて「こういう時につかうんだな!」と感づいた人はすごいです。

例えば1~100の偶数のみを出力するといったときに使用します。
今度はfor文で例を書いてみます。こんな感じになります。


for(var i = 1; i <= 100; i++){
  if(i % 2 != 0){
    continue;
  }
  document.write(i);
}

>if(i % 2 != 0){
これは「i を 2で割ったあまりが0かどうか」という内容になります。
これがtrueという場合、iは奇数ということになります。

今回は偶数のみを出力するなので奇数の場合出力してはいけません。
後続の処理を行わないためにcontinue文を実行し、for文の先頭に戻ります。

もちろん今回の場合


for(var i = 1; i <= 100; i++){
  if(i % 2 == 0){
    document.write(i);
  }
}

と書くこともできます。この場合「iを2で割った余りが0の場合出力する」になります。

今回のような単純な処理の場合、どちらでもそこまで問題ないですが、
continue文を利用したほうが可読性が上がる場合も結構な頻度であるのでぜひ覚えておきましょう。

ただ書けるというだけであれば偶数出力は

document.write(2);
document.write(4);
document.write(6);
・・・

って書いても目的は達成できますけど、ループを使うことでコードを書く量はへりますし、
可読性も高くなります。

可読性、本当に大切です。読みづらいコードバグりやすいです。

■break文とラベル

前回ちょっとだけループのなかにもループが書けるということをいいました。

例えばこんな感じです。


for(var i = 0; i < 10; i++){
  for(var j = 0; j < 10; j++){
    処理;
  }
}

呼びやすさ上
ループ変数がiのループをiループ、
ループ変数がjのループをjループ、
とします。

これは
iループのi = 0の状態でjループが10回行われjループを抜け、iループの先頭に戻り、
iループのi = 1の状態でjループが10回行われjループを抜け、iループの先頭に戻り、
iループのi = 2の状態でjループが10回行われjループを抜け、iループの先頭に戻り、
iループのi = 3の状態でjループが10回行われjループを抜け、iループの先頭に戻り、
・・・
iループのi = 9の状態でjループが10回行われjループを抜け、iループの先頭に戻り、
と100回処理が行われます。

このとき処理内で何かが発生したときにjループもiループも全部終了させたい。
こういった場合にbreak文とラベルという仕組みを使います。

単純にbreak文のみで、以下の様に記載すると


for(var i = 0; i < 10; i++){
  for(var j = 0; j < 10; j++){
    処理l
    if(終了させたい条件){
      break;
    }
  }
}

抜けるのはjループのみで、iループはまた実行されてしまいます。

こういった場合にはループ自体に名称(ラベル)をつけることで解決できます。
ループ自体の名称にexec_loopとつけた場合の例は以下の様になります。


exec_loop:
for(var i = 0; i < 10; i++){
  for(var j = 0; j < 10; j++){
    処理l
    if(終了させたい条件){
      break exec_loop;
    }
  }
}

こうすることで、一回のbreakでiループも終了することが可能です。

■個人的にプログラミングが面白いなーって思うところ。

上の例ではラベルでループを抜けました。
でもこういった書き方もできるっちゃできます。


var canLoop = true;
for(var i = 0; i < 10; i++){
  for(var j = 0; j < 10; j++){
    処理l
    if(終了させたい条件){
      canLoop = false;
      break;
    }
  }
  if(canLoop == false){
    break;
  }
}

ぱっと見意味がわからない人はちょっと眺めてみてください。
booleanを利用して、jループでbreakした場合、iループもbreakするようにしています。

できるっちゃできるけど、ラベルに比べればややこしいですよね。
プログラミングでif文(条件分岐)が増えれば増えるほどバグりやすくなります。
コード量もだけど考えることも増えますしね。

ラベルのほうはif文が1個で済んでいますが、したのcanLoopを利用した場合はif文が2個に増えています。

このように「できることは同じだけど結構色々な書き方がある」ってところが本当に人によって個性はでるし、
面白いなーって思います。

では今回はこんなところでループで使える色々を書いてみました。

次回は演算子とかですかね!

コメント

タイトルとURLをコピーしました