- 制御文の概念を理解する。
- if文、switch文を利用してプログラムを書けるようになる。
プログラミングの世界では条件により、その後の処理の内容を変化させていく方法が頻繁に行われます。条件によって処理の内容を分岐させていくことを条件分岐と言います。JavaScriptが使われるウェブサイトの場合でも時刻によって表示させる内容を変えたり、ブラウザのバージョンによってURLの値を変更したり、その他にも様々な場面で条件分岐は使われます。
このレッスンで学習する**if文やswitch文といった制御文**と呼ばれる文は、そういった条件分岐処理を制御するのに使われます。制御文を使って処理を分岐させていくことでより複雑なプログラムを組むことができるようになります。
プログラミングでは条件分岐を行う際は、**条件式と呼ばれる式を判断します。条件式はその中に記述された条件が真であればtrue、偽であればfalseを返します。このtrueかfalseのどちらを返すのかによってその次に続く処理を分岐させます。この条件分岐の構造を示すものを制御フロー(control structure)**と呼びます。
プログラミンングをしていると、時として条件分岐が複数に枝分かれしてそのプロセスの流れが非常に複雑になることがあります。簡単な条件分岐であれば特に問題ないのですが、複雑な条件分岐の場合、その処理のプロセスを明確に把握しておくことはコードを設計する上でとても重要です。
ここでは先ほど述べた**条件式について説明します。まず以前学習した論理型(Boolean)について簡単に確認しておきます。論理型というのは真と偽**の2つの値しか持たない型のことです。JavaScriptでは真の場合を'true'、偽の場合を'false'という値(論理値)で表します。これらはあくまで論理型の値であって文字列ではないことに注意してください。
さて、プログラムが条件分岐を行う際にどうやって判断を行なっているかというと、すでに述べたように**条件式**というものを評価して真偽の判断を行います。もし条件式が真であればその式はtrueとなり、そうでなければfalseとなります。
簡単な条件式の例として2 > 1という式を考えてみます。「>」はすでに学んだように比較演算子と呼ばれるものです。左右の値の大小を比較し、その計算式が成り立つ場合にはtrue、そうでない場合にはfalseを返します。2 > 1は常に成り立つのでこの条件式は常にtrueを返します。
以下は制御文の一つである**if文**を使った条件分岐の例です。
if(2 > 1){
console.log(typeof (2 > 1)); // boolean
}if文はif(条件式){処理文}という構文を持っていて、条件式が真の場合にのみブロック「{}」で囲んだ中の処理を実行します。今回の例では条件式は真となるので中の処理を実行してくれることになります。
また**typeof演算子**を使って条件式を確認して、確かにこれが論理型であることがわかります。
先ほど条件式で値の大小つを評価するために「>」の不等号演算子を使いました。条件式の真偽を評価するための演算子は、すでにレッスン3で学習した**比較演算子、論理演算子**を使います。 ここでもう一度レッスン3の比較演算子の項目を読んで、制御フローとリンクさせて理解しておくと良いでしょう。
簡単に復習として、trueおよびfalseの論理型の値はそのまま、真および偽として条件式に使うことができる実例を見ておきましょう。
if (true) {
console.log('真'); // 実行される
}レッスン3で学んだ**比較演算子、論理演算子**を使って条件式を評価する上で注意しておきたいこととして、これらの演算子を組み合わせて使う際には、それぞれの演算の順番の優先度を意識しておく必要があるというのがあります。具体的には、論理反転演算子!、<、>、<=、>=の関係演算子、==,===,!=,!==の等価演算子、論理AND&&、論理OR||の順番で優先度が下がって行きます。
if (name === 'Yamada' && !url) {
console.log('YamadaさんのURLは存在しません');
}上の例では論理AND&&が最も優先度が低くなるため、条件式は
「変数nameが文字列'Yamada'に厳密に等しく」かつ「変数urlがtrueでなければ」処理を実行すると解釈できます。
**if文はプログラミングでもっとも頻繁に使われる制御文です。if文は条件式が偽となる場合はブロック内の処理をスキップし、真となる場合のみブロック内の処理を実行します。if文**の制御フローは以下の図のようなイメージになります。
**if文**の基本構文は次のようになります。
if (条件式) {
文;
文;
文;
}サンプルコードを見てみましょう。
let a = 3;
if (a > 0) {
//trueの時に実行
console.log(a); // 3
}if文を実行すると「(条件式)」の中に書かれた式が評価され、判定結果がtrueの場合に
その後ろに続くブロック「{}」の中に記述された命令文が実行されます。ブロックの末尾にセミコロンは必要ありません。制御文でブロック内の処理式を書く際は見通しをよくするためにインデントを入れておくと良いでしょう。
ブロックは通常必要ですが、実行したい文が一つだけの場合は次のようにブロック無しで記述することもできます。
if(条件式) 文;
- サンプルコード
if (true) console.log("true"); // trueif文ブロックの中にさらに**if文**を記述入れ子(ネスト)にすることもできます。これにより、さらに細かい条件分岐ができるようになります。
let obj = {
num: 1,
name: 'ocean',
}
if (obj.num <= 10) {
if (obj.name === 'ocean') {
console.log('値は10以下で、名前は"ocean"です。'); // ここが出力される
}
}**if文**は条件式が真となる場合にのみ処理を実行する制御文でした。else ifおよびelseを使うことで条件式を評価した結果が偽(false)となる場合に、さらなる条件分岐ができるようになります。
else ifを使った基本構文は次のようになります。
//else if文の構文
if (条件式1) {
//条件式1がtrue時に実行
文;
文;
}
else if (条件式2) { //条件1でfalseの時に条件式2を評価
//条件式2がtrue時に実行
文;
文;
}**if文**の条件式がfalseであると判断されるとその直後のelse ifにある条件式を評価しに行きます。これがtrueであればその直後のブロック内の処理を実行します。
**else if文**の中で、else if(条件式)を使う回数に決まりはないので下記のように記述することは問題ありません。
if (条件式1) {
文;
} else if (条件式2) {
文;
} else if (条件式3) {
文;
} else if (条件式4) {
文;
}ただし**else if文は必ず先頭にif文を伴います。else if文を単体で使用することはできません。if文およびelse if文**による条件分岐の結果のどれにもtrueにならない場合の処理を記述したい場合は、制御文の最後にelse{処理文}を追加することで可能になります。この時、if、else if、elseのいずれかのブロックの処理が必ず実行されることになります。
if (条件式1) {
文;
} else if (条件式2) {
文;
} else {
文; // 全ての条件に当てはまらない場合に実行
}- サンプルコード
//街の規模を調べる条件分岐
let population = 1198000;
if (population < 100000) {
console.log("Small City");
} else if (population < 500000) {
console.log("Medium City");
} else if (population < 1200000) {
console.log("Big City");
} else {
console.log("Gigantic City");
}出力結果:
"Big City"
**if文以外の制御文としてswitch文を紹介します。switch文はまず基準となる変数(あるいは式)の中の値を評価します。次にそのswich文のブロック内にその値と一致するcase 値:を探しに行き、もし一致する値がある場合、そのcase以降の文が実行されます。命令文が実行されるとブロックを抜けます。switch文で書ける内容はif文で記述することも可能なので必須ではありませんが、if文**に比べて処理が高速であり、また可読性が良いという特徴があります。
switch文の基本構文は次のようになります。
switch (変数(式)) {
case 値1:
文;
break;
case 値2:
文;
break;
case 値3:
文;
break;
}具体的なサンプルコードをみてみましょう。
let weather = 'sunny';
switch (weather) {
case 'sunny':
console.log('晴れです');
break;
case 'cloudy':
console.log('曇りです');
break;
case 'rainy':
console.log('雨です');
break;
}出力結果
"晴れです"このように変数と一致する値があれば、そのcaseに記述された処理が実行されます。
各caseに続く文章の末尾にbreakが記述されていることに注目してください。**switch文**ではこのbreakを記述しておかないとそれ以降のcase内の文も実行してしまいます。
//breakのないswitch文
let color = 'blue';
switch (color) {
case 'blue':
console.log('青です');
case 'red':
console.log('赤です');
case 'yellow':
console.log('黄色です');
}出力結果:
// コンソールの出力結果
"青です"
"赤です"
"黄色です"上記の構文ではどの値も評価元の値と一致しない場合は、何も実行されずswitchのブロックを抜けます。もし**if文**のelseの場合のように何も該当しない場合の処理を記載する場合は次のようにdefaultを記述しておきます。
switch (式) {
case 値1:
文;
break;
case 値2:
文;
break;
default: // 該当しない場合に実行される
文;
}以下の**switch文**を使ったサンプルコードでは、用意した変数の値と一致するものがないので最後のdefaultの処理が実行されています。
//defaultのあるswitch文のサンプルコード
let color = 'green';
switch (color) {
case 'blue':
console.log('青です');
break;
case 'red':
console.log('赤です');
break;
case 'yellow':
console.log('黄色です');
break;
default:
console.log('該当する色がありません');
}出力結果:
//コンソールの出力結果
"該当する色がありません"先ほども述べたように**switch文はbreakをつけない場合は、それ以降のcase内の文も実行します。この仕組みを使って複数の値に対して一つの結果を返すswicth文**を書くことができます。下記の例では、例えば最初の3つのcaseでラベル付された値�に該当した場合、どの場合も同じ処理文が実行されます。
let bestAnimal = "Lion";
switch (bestAnimal) {
case 'Cat':
case 'Lion':
case 'Fox':
bestAnimal = 'Mammal'; // 'Cat'、'Lion'、'Fox'の場合
break;
case 'Duck':
bestAnimal = "Bird";
break;
default:
bestAnimal = 'Nothing';
}
console.log(bestAnimal); // "Mammal"


