JavaScript/制御構造

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

制御構造(せいぎょこうぞう、control flow)とは、プログラムの流れのことです。単純なプログラムでは上から下へ順番に処理が実行されていきますが、制御構文(せいぎょこうぶん、control flow statement)と呼ばれる文を用いると、ある条件が成立するときのみ処理を実行したり、同じ処理をループしたりすることができます。さらに、無限ループ(むげんループ、infinite loop)についてもこの章で扱います。

概要[編集]

次のプログラムはnが0より小さいときには「負の数」、nが0より大きいときには「正の数」、さもなくば(nが0のときには)「0」と表示します。

var n = 0;

if ( n < 0 ) {
    alert("負の数");
}
else if ( n > 0 ) {
    alert("正の数");
}
else {
    alert("0");
}

順番に見ていきましょう。あせらず、じっくりと考えてください。

if-else[編集]

if文(イフぶん、if statement)は「もし〜ならば」を表す制御構文(条件構文)です。if文のブロックはかっこの中に書かれた条件がtrueであるときのみ実行されます。次のプログラムは、n < 0(nが0より小さい)という条件がtrueであるときのみ「負の数」と表示します。

var n = -1;

if ( n < 0 ) {
    alert("負の数");
}

if文のあとにelse文(エルスぶん、else statement)を置くと、else文のブロックはif文のかっこの中に書かれた条件がfalseであるときのみ実行されます。次のプログラムは、n < 0(nが0より小さい)という条件がtrueであれば「負の数」、さもなくば(nが0以上ならば)「自然数」と表示します。計算機科学では一般に0を自然数に含めます。

var n = 0;

if ( n < 0 ) {
    alert("負の数");
}
else {
    alert("自然数");
}

if文とelse文をあわせてif-else文と呼びます。else文は必ず直前のif文とくっつくので、if文とelse文の間に余計な文を入れることはできません。if-else文は次のように何個もつらねることができます。

var n = 0;

if ( n < 0 ) {
    alert("負の数");
}
else if ( n > 0 ) {
    alert("正の数");
}
else {
    alert("0");
}

このプログラムはn < 0ならば「負の数」、そうでなくn > 0ならば「正の数」、そうでもないならば「0」と表示します。else ifという部分に注目してください。何通りもの条件で処理を分岐したい場合は、このelse ifを何個も増やしていくことになります。if文やelse文のブロックの中に単文(1つの文)しか入っていない場合は、ブロックを省略することができます。すなわち、次のように書いても同じことです。

var n = 0;

if ( n < 0 )
    alert("負の数");
else if ( n > 0 )
    alert("正の数");
else
    alert("0");

なお、この場合は条件演算子を用いて簡潔に書くこともできます。

var n = 0;

alert( n < 0 ? "負の数"
     : n > 0 ? "正の数"
     :         "0" );

if文の条件式はすべてtrueかfalseの真偽値として評価されます。たとえば、数値の0は真偽値に変換するとfalseになるので、次のif文のブロックは絶対に実行されません(デッドコード)。

if ( 0 ) {
    // たどりつけない
}

これを利用すると、nが0に等しいかどうかは if ( n == 0 ) { /* ... */ } のほかに if ( !n ) { /* ... */ } と書くこともできます。同様に、nが0に等しくないかどうかは if ( n != 0 ) { /* ... */ } のほかに if ( n ) { /* ... */ } と書くこともできます。この知識は次の例題をエレガントに解くのに必要になるかもしれません。

  • 例題

整数の偶奇判別プログラムを書け。

  • 解答

if-else文を用いる場合は、

if ( n % 2 == 0 ) {
    alert("偶数");
}
else {
    alert("奇数");
}

または

if ( n % 2 ) {
    alert("奇数");
}
else {
    alert("偶数");
}

条件演算子を用いる場合は、

alert( n % 2 == 0 ? "偶数"
                  : "奇数" );

または

alert( n % 2 ? "奇数"
             : "偶数" );

または

alert( ( n % 2 ? "奇"
               : "偶" ) + "数" );

など。

switch[編集]

switch文(スイッチぶん、switch statement)は、if-else文を何個もつらねて書くのが面倒な場合に用いられます。

if ( keyCode == 37 ) {
    alert("←");
}
else if ( keyCode == 38 ) {
    alert("↑");
}
else if ( keyCode == 39 ) {
    alert("→");
}
else if ( keyCode == 40 ) {
    alert("↓");
}

これはswitch文を使って次のように書くことができます。

switch (keyCode) {
    case 37:
        alert("←");
        break;
    case 38:
        alert("↑");
        break;
    case 39:
        alert("→");
        break;
    case 40:
        alert("↓");
        break;
}

必ずcase節の最後にbreak文を書くのを忘れないでください。なお、たいていのケースではswitch文を使わなくても、連想配列を応用したディスパッチテーブルで事足ります。switch文はここぞというときに使ってください。

alert( { 37: "←", 38: "↑", 39: "→", 40: "↓" }[keyCode] );

while[編集]

いよいよループの登場です。while文(ホワイルぶん、while statement)は条件がtrueである間、ブロックを実行しつづけます。

var i = 0;
while ( i < 10 ) {
    alert(i);
    i++;
}

iはinteger(整数)の頭文字です。このプログラムはまず、1行目で変数iに0を代入しています。次にi < 10がtrueであるかを確かめます。trueなのでブロックを実行し、iを表示してiを0から1に増やします。そして再び条件式に戻り、i < 10がtrueであるかを確かめます。trueなのでブロックを実行し、iを表示してiを1から2に増やします。

10回ループが回るとiが10になり、i < 10がfalseになるのでループを抜けます。このようにwhile文はi < 10がtrueである間、ブロックを実行しつづけます。よってこのプログラムは0から9までの数字を表示します(10になるとループから抜ける)。

while文は条件式がtrueであれば延々とループを回し続けるので、いつまで経ってもfalseにならないような条件を指定すると無限ループになります。無限ループが発生すると処理系がフリーズする場合があるので注意してください。以下のプログラムは、絶対に実行しないでください。

while ( true ) {
    break;
}

ウェブブラウザ上のJavaScriptで本当に無限ループがほしい場合は、window.setIntervalなどのメソッドを使用します。

setInterval(function(){
    // ビジーウェイト
}, 0);

JavaScriptではwhile文に空の条件式を指定することはできません。

do-while[編集]

do-while文(ドゥ・ホワイル文、do-while statement)は、まずdo文のブロックを実行し、次にwhile文の条件式を確認してループします。次のプログラムは0から9までの数字を表示します。

var i = 0;
do {
    alert(i);
    i++;
}
while ( i < 10 );

for[編集]

for文(フォー文、for statement)は、var i = 0のような変数の初期化と、i < 10のような条件式と、i++のような変数の更新を一行で書くことができる最も一般的かつ実用的な制御構文です。JavaScriptではwhile文やdo-while文はあまり使われませんが、for文はループを簡潔に書けるので非常に重宝します。次のプログラムは0から9までの数字を表示します。

for ( var i = 0; i < 10; i++ ) {
    alert(i);
}

var i = 0はループに入る前に一度だけ実行されます。次にi < 10がtrueならばブロックを実行し、i++を実行して再び条件式に戻ります。i < 10がtrueである間、ブロックの実行と変数の更新が行われるということです。for文はかっこの中に3つの式を書ける強力な制御構文なので、他の構文はすべてfor文の特別な場合であるとも考えられます。

たとえば、配列の要素を1つずつ取り出して処理をするような場合はfor文を使います。

var array = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
for ( var i = 0, l = array.length; i < l; i++ ) {
    alert( array[i] );
}

単文の場合はブロックを省くことができます。

var array = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
for ( var i = 0, l = array.length; i < l; i++ )
    alert( array[i] );

後置インクリメント演算子は変数の値を1増やし、増やす前の値を返すので、次のように書くこともできます。

var array = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
for ( var i = 0, l = array.length; i < l; alert( array[i++] ) );

このような書き方をしても読みにくいだけですが、こちらの方が簡潔だという人もいるでしょう。

break[編集]

break文(ブレーク文、break statement)はループまたはswitch文を途中で抜けます。次のプログラムはiが5になった時点でfor文のループを抜けるので、0から4までの数字を表示します。

for ( var i = 0; i < 10; i++ ) {
    if ( i == 5 ) break;
    alert(i);
}

すぐに気づいた人もいるでしょうが、while文の無限ループの例は実際には無限ループになっていません。

continue[編集]

continue文(コンティニュー文、continue statement)はループを次に進めます。次のプログラムは0から9までの数字を表示しますが、4だけは死に通じるため表示しません。

for ( var i = 0; i < 10; i++ ) {
    if ( i == 4 ) continue;
    alert(i);
}

ラベル[編集]

ラベルを使用すると深いループを一気に抜けたり、進めたりすることができます。

LOOP:
for ( var x = 0; x < 10; x++ ) {
    for ( var y = 0; y < 10; y++ ) {
        if ( y == 5 ) break LOOP;
        alert( [ x, y ] );
    }
}

その他の制御文[編集]

with文[編集]

with文の用途は、実際のコードを見ると良い。次の2つの関数は同じ意味である。

function math1(){
  document.write( Math.ceil(10.5) );	// 小数点切り上げの値を表示
  document.write( Math.PI );	// 円周率πを表示
}

function math2(){
  with( Math ){
    document.write( ceil(10.5) );	// 小数点切り上げの値を表示
    document.write( PI );	// 円周率πを表示
  }
}
math1();
math2();

この様に、あらかじめwith文で予約しておくことで、それに続く文の間では、親オブジェクトの名前を省略することが出来る。 これはVBScriptなどの言語から採用されたものである。

void文[編集]

この演算子はundefinedを返す。

何も処理を行わないことをプログラム中で明示したい場合にこの演算子を利用する。 実際の用途は非常に限られる。

new演算子[編集]

オブジェクトのクローンを作成する。

delete文[編集]

delete演算子 オブジェクトからプロパティを取り除く演算子である。 この演算子は、オブジェクト指向を理解してから利用すべき演算子であるので説明は後の項に回す

このページ「JavaScript/制御構造」は、書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にノートへどうぞ。