第1章 JavaScript導入ガイド

制御構造

2009年8月4日

プログラムの制御構造

プログラムは記述したとおりに、命令文を上の行から順番に処理されます。制御構造は、その実行順番を制御するためのもので、条件分岐やループなどの構成要素があります。

条件分岐

「もし~ならば、・・・を実行する」という条件つき命令は、プログラムの流れを制御するときによく利用されます。JavaScriptでは、if else文とswitch文をサポートしています。

if else

if~elseは、カッコ( () )で囲んだ論理式を評価し、式の値が真ならifブロック内の命令を、偽りならelseブロック内の命令を実行します。

構文
if ( 論理式 ) {
1つ目のifブロック内の命令
} else if ( 論理式 ) {
2つ目のifブロック内の命令
} else {
elseブロック内の命令
}

次の式のように、論理式が真の場合、ifブロックが処理されてtrueが出力されます。もし、式の値が偽りであれば、elseブロックが処理されてfalseが出力されます。

// 論理式の値が true の場合
if ( true ){
console.log("true");
// 論理式の値が false の場合
} else {
console.log("false");
}
true

if〜elseは、ifで指定した論理式が真の場合と偽りの場合の2択で条件分岐されますが、それ以上の分岐が必要な場合はelse ifを使います。
次の文は、変数xの値が「A」の場合はifブロック、「B」の場合はelse ifブロック、どちらにも当てはまらない場合はelseブロック内の命令文が処理されます。

// x の値で処理を分岐させる
if ( x == "A" ){
// else ifは必要なだけ増やせる
} else if ( x == "B" ) {
// どの論理式にも当てはまらなかった場合
} else {
}

if や else if は、複数の論理式を論理演算子の && もしくは || を使って組み合わせることができます。

// x の値が A、 もしくはB のとき
if ( x == "A" || x == "B" ){
....
}
// x の値が A、なおかつ y の値が B のとき
if ( x == "A" && y == "B" ){
....
}

else if、elseは省略可能で、ifのみにすることもできます。
例えば、変数 x の値が「A」の時だけ出力するには次のようになります。

if ( x == "A" ) {
console.log(x);
}

さらに、ifに続く命令が1文のときには、{ }を省略することができます。 {} を省略した場合、命令文は1行までが有効です。

// 上記と同じ文で {} を省略
if ( x == "A" ) console.log(x);

[COLUMN] 処理速度を考えた書き方

if else が複数必要な場合、その順番にも注目したいです。例えば、変数 x の値で条件分岐する if 文があり、xの値で最も可能性が高いのが「C」だったとします。

// xの値が「C」の場合、この条件分岐は飛ばされる
if ( x == "A" ){
// xの値が「C」の場合、この条件分岐は飛ばされる
} else if ( x == "B" ) {
// xの値が「C」の場合、この条件分岐が処理される
} else if ( x == "C" ) {
}

上記のような条件分岐の順番だと、3番目の条件分岐にたどり着くまで2回、論理式の評価が行われます。もし3番目の条件式が一番上であれば、論式式の評価は1回だけで済んでいました。

効率を考えると、可能性の高い条件分岐から順番に評価するのがベストです。

// xの値が「C」の場合、この条件分岐が処理される
if ( x == "C" ){
} else if ( x == "A" ) {
} else if ( x == "B" ) {
}

読みやすさなどを考えると必ずしも上記の書き方だけが正解とはいえないので、読みやすさや、無駄な処理が発生しないかなどを複合的に考えて、条件分岐の順番を決めると良いでしょう。

switch

switch文は、一つの式を評価し、その値にマッチするラベルに制御を移します。

switch ( 式 ) { 
case 値:
処理
break;
case 値:
処理
break;
default:
処理
break;
}

if文はandやorを使った論理式を使えますが、switch文は一つの式の値で処理を分岐させます。
switch文の処理の流れとしては、まず式が評価され、その値とマッチするcaseラベルが上から順番に検索されます。caseで指定した値と式の値がマッチした場合、関連した命令文が実行されます。

次のようなif文と同じ処理になるswitch文を作ってみましょう。まずはif文です。

if ( x == "A" ){
// ここに命令文を記述
} else if ( x == "B" ) {
// ここに命令文を記述
} else {
// ここに命令文を記述
}

次にswitch文です。switch文の場合、if、else ifの代わりにcaseを使って分岐させ、elseの代わりにdefaultを使います。

switch ( x ) {
case "A":
// ここに命令文を記述
break;
case "B":
// ここに命令文を記述
break;
default:
// ここに命令文を記述
break;
}

defualtはcaseに当てはまらなかった場合に、そのブロック内の命令文が必ず実行されます。defaultは省略可能です。
breakラベルはswitchの処理を終了させます。breakを省略した場合、マッチしたcaseブロックの処理が終わった後、次のラベルが評価されます。

if文の方がシンプルに使え、論理式により条件分岐するため、殆どの条件分岐ではif文が使われます。値によって条件分岐したいとき、switch文を使うことを検討すると良いでしょう。

ループ

JavaScriptはfor文とwhile文の2つのループ構造をサポートします。
ループは指定された条件が満たされるまで、くり返し命令文を処理します。

for

for文は、指定された論理式がfalseになるまで処理を繰り返します。

for ( 初期化式; 論理式; 増加文; ) {
命令文
}

for文の処理を追っていくと、まず、初期化式でループカウンタと呼ばれる、ループ処理の回数を決める変数を初期化します。この初期化式は、最初の1回だけ処理されます。
次に論理式が評価されます。論理式がtureを返す間は、for文のブロック内が繰り返し実行されます。論理式がfalseを返した場合、forループが終了します。
増加文では指定した変数(通常はループカウンタ)をインクリメント、デクリメントします。

次のようなfor文では、まず変数iが0に初期化され、次に論理式が評価されます。この論理式は変数iが5未満の間はtrueを返し、その間はブロック内の命令文を繰り返し実行します。すべての命令文が実行されると、また次のループへ戻る前に、増加文が評価されます。ここでは変数iがインクリメントされます。
i、j、kがループカウンタの変数名としてよく使われています。

for ( var i=0; i<5; i++; ) {
console.log( i );
}

for文を含む繰り返し文は、ループカウンタを使って繰り返し回数を制御します。for文は、このループカウンタを初期化して、条件判定、更新を1行で設定することができるため、繰り返し分の中で最もよく使われています。

初期化式と増加文は複数の対象をカンマで区切って指定することができます。

for ( 初期化式, 初期化式, ...; 論理式; 増加文, 増加文, ...; ) {
命令文
}

次のfor文は変数iと変数jを初期化し、iが3以下の間は繰り返しブロック内の命令文を実行します。増加文ではiをインクリメント、jをデクリメントしています。

for ( var i = 1, j = 3; i <= 3; i++, j--){
console.log("i = " + i + "  j = " + j);
}
i = 1  j = 3
i = 2  j = 2
i = 3  j = 1

while

while文は式がtrue(真)の間、ブロック内の命令文を繰り返し実行します。式がfalseの場合、ブロックを抜けて次の処理に移ります。

while( 式 ){
命令文
}

次のwhile文は変数xが3未満の間ループを繰り返します。

var x = 0;
while( x < 3 ) {
console.log(x);
x++;
}

指定した式がfalseにならない場合、命令が永遠に実行されるので注意してください。
whileに指定する式が、たとえば変数xが10以下の間は繰り返すであれば、ブロック内で変数xをインクリメントして、いずれ10になるようにする必要があります。
下記では、変数xが10で、式は変数xが3以上であれば繰り返すので、無限に繰り返されてしまいます。

var x = 10;
while( x > 3 ) {
console.log(x);
x++;
}

do while

do while文はまずdoブロックを実行し、式が真の間はdoブロックを繰り返し実行します。doブロックを実行した後で式を判定するので、doブロック内の命令文は少なくとも1回は実行されます。

構文
do {
命令文
} while ( 式 );

次の例文では、while の条件が TRUE の間、doブロック内の処理を続けます。

var i = 0;
do {
i++;
console.log(i);
} while ( i < 5 );

最低1回はブロックを実行したい、というケースが少ないため、do while文はあまり使われていません。

break

breakはwhileやforといったループやswitchなどの処理内で使われます。beakが実行されると直ちにそのループやswitch処理から抜けて次の命令文に移動します。

次のfor文では、変数iが10未満の間繰り返されますが、ブロック内のif文で、iが3になった際に、breakが実行されています。そのため、出力結果は0から2までとなります。

for ( var i = 0; i < 10; i++ ) {
if ( i == 3 ) {
break;
}
console.log(i);
}
0
1
2

continue

while、for文のブロック内でcontinueが評価されると、それ以降に続くブロック内の命令をスキップし、先頭ループへ戻ります。

conticueは、breakと同様に処理を中断させますが、その後ループの先頭に処理を戻します。次のfor文では、変数iが3のときにcontinueが実行されるので、0から2まで出力されたあと、3が飛ばされて、4が出力されています。

for ( var i = 0; i < 5; i++ ) {
if ( i == 3 ) {
continue;
}
console.log(i);
}
0
1
2
4

オブジェクト操作命令

for~in

for in文は、指定したオブジェクトのプロパティ名を取り出し、変数に代入します。オブジェクトから列挙可能なプロパティがある間繰り返し処理されます。

for ( 変数 in オブジェクト ) { 
命令
}

次の例では、変数objを初期化し、for inを使ってすべての要素にアクセスしています。

var obj = {a:"A", b:"B", c:"C"};
for ( var o in obj ) {
console.log("obj." + o + " : " + obj[o]);
}
obj.a : A
obj.b : B
obj.c : C

for inは配列に対しても使うことができます。配列の場合はインデックスが変数に代入されます。
ただし、for inはインデックス以外にも、カスタムプロパティやカスタムメソッドなどもループ処理の対象となるので、配列の場合は通常のforループを使ったほうが安全です。

var obj = ["A", "B", "C"];
for ( var i in obj ) {
console.log("obj." + i + " : " + obj[i]);
}
obj.0 : A
obj.1 : B
obj.2 : C

return

returnは関数中で使います。returnが実行されると、直ちに関数を終了します。returnに値を指定すると、関数はその値を呼び出し元に返却します。値を返さない関数の場合、returnの式は不要です。

return 式

下記の関数は引数 x と y を乗算して返します。

unction pow(x,y){
return x * y;
}

with

withは、オブジェクトのプロパティやメソッドを頻繁に参照する際に有用です。withで指定したオブジェクトは、そのブロック内で省略することができます。

with( オブジェクト ){
命令
}

次の式は、Mathオブジェクトのminとmaxを、オブジェクト名なしで参照しています。

var a = 5, b = 10;
with ( Math ) {
console.log("最小:" + min(a,b));
console.log("最大:" + max(a,b));
}
最小:5
最大:10

withは使用を推奨されていません。オブジェクトはバージョンにより変更されるため互換性にかけ、パフォーマンスもよくありません。

Comment

  1. まとめてのご返答になりますが、ご指摘ありがとうございます。
    修正しました。

  2. var
    n = 0

    for (var i = 0; i <9; i++){
    n +="i"
    }
    document.write(n);

    実の実行結果は「36」ではなく、「0iiiiiiiii」です

  3. ご指摘ありがとうございます。
    修正しました。

  4. thisの項の文章で漢字の変換間違いを発見しました。

    >またはインスタンス 自信 を示します。

コメントを残す

メールアドレスが公開されることはありません。

関連記事

リズムファクトリーはホームページの制作会社です。
ホームページ制作に関するご要望・ご相談はこちらからどうぞ。

株式会社リズムファクトリーでは現在、下記の職種について人材募集を行っております。
求人をクリックすると「求人情報サイトFind Job!」の求人詳細画面が開きますので、こちらからご応募下さい。

提供 : Webな人の求人情報サイト Find Job!