【JavaScript】制御命令①
長かった演算子も終わり
お次は制御命令です
プログラムの3つの構造
- 記述された順番に処理を行っていく順次(順接)
- 条件によって処理を分岐する選択
- 特定の処理を繰り返し実行する反復
JSの分岐
JSでは処理を分岐するための命令として
下記の二つが存在する
- if命令
- 2つから片方を選択する(単純分岐)
- switch命令
- 複数の選択から一つを選択する(多岐分岐)
ちょこちょこftlやらでも
やっていたことなので分かると思うが
記述の方法が違うんだろうなー
ふむ、詳細を!
単純分岐を記述する(if命令)
「もし~だったら‥、さもなくば‥」
という構造を表現するためのもの
与えられた条件式の
true/falseという戻り値によって
対応する命令(群)を実行する
下記構文
if (条件式1) { 条件式1がtrueの場合に実行する命令 } [else if (条件式2) { 条件式2がtrueの場合に実行する命令 } [else { 全ての条件式がfalseの場合に実行する命令 }]]
具体例!みてみる!うす!
var x = 15; if (x >= 20) { document.writeln('変数xは20以上!やったね!'); } else if (x >= 10) { document.writeln('変数xは10以上!ひゃほー!'); } else { document.writeln('変数xは10未満‥( ;∀;) '); } //変数xは10以上!ひゃほー!
この例の場合
- 変数xの値が20以上の場合 ⇒ 「変数xは20以上!やったね!」
- 変数xの値が10以上の場合 ⇒ 「変数xは10以上!ひゃほー!」
- 変数Xの値が10未満の場合 ⇒ 「変数xは10未満‥( ;∀;)」
のようなメッセージが表示される
elseブロック、elseifブロックは省略ができる
うむ、こういう概念的なところは
いままで書いてたテンプレートエンジンでも
同じだからわかる
一応メモだが
if命令の場合複数の条件に合致する場合でも
最初のブロックのみ実行される
さっきの具体例でいうと
var x = 30; if (x >= 10) { document.writeln('変数xは10以上!ひゃほー!'); } else if (x >= 20) { document.writeln('変数xは20以上!やったね!'); } else { document.writeln('変数xは10未満‥( ;∀;) '); } //変数xは10以上!ひゃほー!
この形だと最初の条件式で合致してしまったので
elseifブロックは無視されてしまう
条件の順番には気をつけろ、ってことね
あとあとif命令は入れ子にすることで
より複雑な条件分岐を表現することが可能!
さっきのも入れ子にして
var x = 30; if (x >= 10) { if (x >= 20) { document.writeln('変数xは20以上!やったね!'); } else { document.writeln('変数xは10以上!ひゃほー!'); } } else { document.writeln('変数xは10未満‥( ;∀;) '); } //変数xは20以上!やったね!
こんな感じに書いてあげれば
いい感じに動いてくれる、うむー!
制御命令を入れ子にすることを
ネストするといったりもする、うんしってた!
これからやるswitch/for/do..while/whileなどの制御命令でも
ネスト構造にすることができる
コードの可読性の観点から
あまり深いネスト構造にするのは避けるべきだけれど
ネストの深さに応じてインデント(段落)をつけることで
視覚的にコードを読みやすくすることができる
これはなんでも一緒だなー
CSSもHTMLもテンプレートエンジンもなんでも
中カッコは省略可能
ブロックの中の命令が1文の場合に限り
中カッコ({‥})を省略することができる、ほう‥
var x = 15; if (x >= 10) document.writeln('変数xは10以上!ひゃほー!'); else document.writeln('変数xは10未満‥( ;∀;) '); //変数xは10以上!ひゃほー!
だがしかしブロックの範囲が不明確になるため
バグを生みやすくなるので推奨しない、とな
ネストするケースで考えるとわかりやすいとな
var x = 1; var y = 2; if (x == 1) if (y == 1) document.writeln('変数x、yはともに1です'); else document.writeln('変数xは1ではありません'); //変数xは1ではありません
本当は何も返さないのが正しい挙動になるが
elseブロックが意図せず
「x == 1」ではなく「y == 1」に対応しているため
「変数xは1ではありません」が表示される
中カッコを省略した場合、elseブロックは
直近のif命令に対応したとみなされる
ということね、なるほどー!
やっぱりちゃんと中カッコを書いた方がいいね!
var x = 1; var y = 2; if (x == 1) { if (y == 1) { document.writeln('変数x、yはともに1です'); } } else { document.writeln('変数xは1ではありません'); }
うん、まちがいない!
多岐分岐を記述する(switch命令)
はい、以下構文!
switch (式) { case 値1 : 「式 = 値1」である場合に実行される命令(群) [case 値2 : 「式 = 値2」である場合に実行される命令(群) [case 値N : 「式 = 値N」である場合に実行される命令(群) ... [default : 式の値がすべての値に合致しない場合に実行される命令(群)]]] }
switch命令の処理の流れ
- 先頭の式がまず評価される
- 1の値に一致するcaseブロックを実行する
- 一致するcaseブロックが見つからない場合には、最終的にdefaultブロックを呼び出す
defaultブロックは任意だけれど
どのcaseブロックにも一致しなかった場合の挙動を
明確にするためにも省略しないことを推奨する
ほっほーう
はい!具体例!
var rank = 'B'; switch (rank) { case 'A' : document.writeln('Aランク!さすがっす!!'); break; case 'B' : document.writeln('Bランク!がんばりました!'); break; case 'C' : document.writeln('Cランク!まだまだいけます!'); break; default : document.writeln('ランク外‥がんばりましょう!'); } //Bランク!がんばりました!
それぞれのcaseブロックの末尾にbreak命令をして
現在のブロックから処理を脱出している
switch命令は合致するcaseブロックに処理を移動するだけで
caseブロックを終了したところで
自動的にswitchブロックから脱出するしくみは備えていない
なんでそうしたのこれw
break命令を指定していない場合
次のcaseブロックが続けて実行されてしまうので
意図した結果が得られないので注意
えじゃあなんでdefaultブロックには
break命令がないの?ってなったので
defaultブロックの位置を変えて確認してみますた
結論、最後だからってだけなのね
閉じカッコ前はbreak命令なくても
続けて実行する処理が存在しないからなくても可
defaultブロックが他のcaseの間にあった場合
defaultでもbreak命令は必要、うむ
意図的にbreak命令を略記して
複数ブロックを続けて実行する(フォールスルー)という書き方もできるが
コードの流れがわかりにくくなる原因となるので
通常は避けるべきだそうな、そうかー
ただし例外として以下のようなケースでは
複数ブロックをbreak命令をはさまずに続けて
記述しても可
var rank = 'B'; switch (rank) { case 'A' : case 'B' : case 'C' : document.writeln('合格!(・∀・)イイ!!'); break; case 'D' : document.writeln('不合格!(´;ω;`)'); break; } //合格!(・∀・)イイ!!
この例では変数rankがA、B、Cのとき
「合格!(・∀・)イイ!!」というメッセージを
Dの場合「不合格!(´;ω;`)」というメッセージを
それぞれ表示するます、ふむー