JavaScriptには他の言語にあるようなgoto文というのは存在しません。
しかし同じでないものの似たような処理ができるのがlabeled文という構文
ここではそのlabeled文の使い方とコード例を紹介したいと思います。
このページの目次
labeled文とは
labeled文はgoto文と似ています。
しかしgotoと決定的に違うのはラベルが置ける場所が決まっていること
labeled文の場合は次のようにステートメントの前にしかラベルは置けません。
1 2 |
ラベル: ステートメント |
ステートメントというのは while や for などのループ、 switch などの処理の塊のこと
そしてラベルの使用用途も限定的で
あるステートメント全体を break または continue するために使う
ことしかできません。
つまりラベル label があるとしたら次の2通りの書き方でループなどを抜け出せるということ
1 2 3 4 5 |
/**あるステートメント内でラベルに対してbreak...*/ break label; /** あるステートメント内でラベルに対してcontinue */ continue label; |
こうすれば label の存在する前のステートメントまで break または continue できます。
ただこれだけだと分かりにくいと思うので具体的なコード例を使って説明しましょう。
labeled文でのcontinueとbreakのコード例
あるラベル label があるときJavaScriptでは goto label; の代わりに
- break label;
- continue label;
のどちらかが使えます。
それぞれの使い方とコード例については次の通り
continue label;
まず初めは continue を使ったlabeled文について
これはループ限定で使える構文で、一番外側のループに continue したいときなどに使えます。
例えば単純なforを使った二重ループを考えてみましょう。
その中である条件で外側に対して continue しているのが次のコード例
1 2 3 4 5 6 7 8 9 10 11 12 |
var i, j; outerloop: for(i = 0; i < 3; i++){ for(j = 0; j < 3; j++){ if(i === 1 && j === 1){ /** 外側のループに対してcontinue */ continue outerloop; } console.log('i = ' + i + ', j = ' + j); } } |
まず初めにfor文の前に outerloop というラベルを設置してます。
そして
i === 1 && j === 1 の条件を満たす場合、
ラベルがある一番外側のfor文に対して
continue するといった感じ
ただし continue outerloop; はラベルのある場所まで戻るという意味ではありません。
あくまでラベルの下にあるステートメントまで戻るという処理になることに要注意
そしてこのコードの実行結果は次の通りです。
1 2 3 4 5 6 7 |
i = 0, j = 0 i = 0, j = 1 i = 0, j = 2 i = 1, j = 0 i = 2, j = 0 i = 2, j = 1 i = 2, j = 2 |
普通の continue なら内側のループで処理を飛ばすだけです。
しかし上の実行結果を見ればわかるように外側まで continue されてるのが分かると思います。
これが continue でのlabeled文の使い方
もちろんfor文だけでなく、while文とかdo while文でも使用可能
ラベルのあるステートメントに対して continue してるだけです。
break label;
お次は break を使ったlabeled文について
これはラベルのある場所に対して break する点は continue の場合と同じです。
しかし違うのはループ以外にもswitch文など break が使える構文全てで使用可能なこと
switchなどで使う場合のコード例は後で紹介します。
ではとりあえず二重ループのコード例で考えてみましょう。
先ほどの continue のコード例を break で置き換えたのが次のコード例
1 2 3 4 5 6 7 8 9 10 11 12 |
var i, j; outerloop: for(i = 0; i < 3; i++){ for(j = 0; j < 3; j++){ if(i === 1 && j === 1){ /** 外側のループに対してbreak */ break outerloop; } console.log('i = ' + i + ', j = ' + j); } } |
break outerloop; となっている個所に注目してください。
こうすることで一番外側のループまで一気に抜けることが可能です。
ちなみにこのコードの実行結果は次の通り
1 2 3 4 |
i = 0, j = 0 i = 0, j = 1 i = 0, j = 2 i = 1, j = 0 |
普通の break とは違い、 break outerloop; した場所で処理が止まっているのが分かるはずです。
以上が break label; を使ったlabeled文の使い方
これは多重ループを一気に飛ばしたり抜けるときに便利そうですね。
labeled文を使った実用的(?)なコード例
次にlabeled文を使った実用的かもしれないコード例を紹介
まあ実用的でなくてもlabeled文の処理を理解するのには役立つと思います。
ケース1. ある行列に0が含まれているか調べる
例えば2次元配列などの行列に1つ以上0が含まれているか調べたいとします。
その場合、0が1つでも見つかればそれ以上処理を続行するのは無駄ですよね。
そんな場合にlabeled文が役に立ちます。
実際のコード例はこんな感じ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
var matrix = [[7, 4], [0, 1], [6, 2]]; var foundZero = false; /** 0が含まれているかどうか調べる */ outerloop: for(i = 0; i < matrix.length; i++){ for(j = 0; j < matrix[i].length; j++){ if(matrix[i][j] === 0){ foundZero = true; break outerloop; } } } if(foundZero){ console.log('Found zero in matrix'); }else{ console.log('NOT Found zero in matrix'); } |
この処理は0が見つかった時点で一番外側のループまで break します。
なのでそれ以降の無駄なループ処理を省けるという訳です。
ケース2 : switch内でlabeled文を使う
今までfor文などのループ内でのlabeled文しか紹介してきませんでした。
ですが実はswitch内でも break に対してlabeled文を使うことが可能です。
例えば次がそのコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
var sweet = 'pie', flavor = "apple"; outerswitch: switch(sweet){ case 'pie': var pieName = ''; switch(flavor){ case 'apple': pieName = 'Apple Pie'; break; default: /** 一番外側のswitchに対してbreak */ break outerswitch; } console.log(pieName); break; case 'cookie': /** ... */ break; } |
break outerswitch; という部分に注目
こう書くことで二重switch内で一番外側に対してbreakすることが可能です。
これは default でだけ特別な処理をしたい場合などに役立つかもしれません。
ちなみに PHP で goto文 を使うには・・・
ちなみにPHPでもgoto文は使用可能。
その使い方を知りたい方は次記事をご覧ください。
▼ PHPでのgoto文の使い方と2つの制約
PHPでの goto文 にも制限があります。
でも制限がある分、危険なコードを書かずに済むかも。
ここまでのまとめ
ということでlabeled文についてもう一度まとめ
- あるステートメントの前にラベルを置く
ただしステートメントは continue または break が使えるもののみ
具体例を挙げるなら for 、 while 、 do while 、 switch , etc... - ラベルを置いたステートメント前まで飛べる
break label; または continue label; でステートメントまでジャンプ
ただしgoto文とは違い、直接ラベルに飛んでいるわけでないので注意
なんとなくgoto文と似てますが、動作や使い方はかなり違いがあるみたいです。
あと自由自在に飛べるわけではないのでスパゲティ
多重ループや多重のswitch文で一気に外側まで戻りたい場合に便利だと思います。