【JavaScript入門】制御構文

条件分岐

制御構文とは、コードが実行される処理の流れを条件分岐したり、繰り返したりといった制御するものです。記述された順番通りではなく、途中で別の流れに変更します。

if文

if文は、条件式がtrueの場合に、指定されたブロックを実行する制御構造です。以下は、基本的なif文の構文です。

 if (条件式) {
   // 条件式がtrueの場合に実行されるコードブロック
 }

条件式は、trueまたはfalseに評価される式です。trueに評価される場合は、if文に続くブロックが実行されます。falseに評価された場合は実行されずスルーします。

例えば、変数xが10未満の場合にメッセージを出力するif文を書くと、以下のようになります。

 let x = 5;
 if (x < 10) {
   console.log("xは10未満です。");
 }

この場合、xが5であるため、条件式x < 10はtrueに評価されます。そのため、if文に続くブロックが実行され、コンソールに「xは10未満です。」というメッセージが出力されます。

値をそのまま条件式として使う

if文では値をそのまま条件式として使うことができます。条件式として渡された値が数値や文字列だった場合、真偽値に自動的に変換されます。数値は0以外なら真、0なら偽、文字列は1文字以上あれば真、1文字もなければ(空文字)偽と扱われます。

以下は、値(数値と文字列)をそのまま条件式として使ったif文の例です。

 let num = 0;
 if (num) {
   console.log("真です");
 } else {
   console.log("偽です");
 }
 // 出力: 偽です
 num = 1;
 if (num) {
   console.log("真です");
 } else {
   console.log("偽です");
 }
 // 出力: 真です
 num = -1;
 if (num) {
   console.log("真です");
 } else {
   console.log("偽です");
 }
 // 出力: 真です
 
 let str = "";
 if (str) {
   console.log("真です");
 } else {
   console.log("偽です");
 }
 // 出力: 偽です
 str = "Hello, world!";
 if (str) {
   console.log("真です");
 } else {
   console.log("偽です");
 }
 // 出力: 真です

また、条件式に使われた値がundefined、null、NaNである場合にもfalseとなります。

 if (null) {
   console.log("実行されません");
 }
 
 if (undefined) {
   console.log("実行されません");
 }
 
 if (NaN) {
   console.log("実行されません");
 }

値をそのまま条件式として使用する場合は、値が特定の範囲内にあるかどうかを判定する場合や、変数が定義されているかどうかを判定する場合などに便利です。ただし、可読性を考慮すると、明確な真偽値の条件式を使用することが推奨されます。

if else文

if…else文は、条件に応じて異なる処理を実行するための制御構造です。if文だけでも一定の制御はできますが、elseを加えることで、条件式がfalseの場合に別の処理を実行することができます。

以下はif…else文の基本的な使い方です。

 if (条件式) {
   // 条件が真の場合に実行される処理
 } else {
   // 条件が偽の場合に実行される処理
 }

この場合、まず条件式を評価し、その結果がtrueであればifブロックの中の処理が実行されます。条件式がfalseであれば、elseブロックの中の処理が実行されます。また、if…else文は、ネストすることができます。

以下は、if…else文を使用したサンプルコードの例です。

 let age = 25;
 
 if (age >= 20) {
   console.log("成人です");
 } else {
   console.log("未成年です");
 }

この例では、ageが20以上の場合には、”成人です”というメッセージが、20未満の場合には、”未成年です”というメッセージがコンソールに出力されます。

以下は、if…else文をネストした例です。

let x = 8;

if (x < 10) {
  console.log("xは10未満です");
} else {
  if (x === 10) {
    console.log("xは10です");
  } else {
    console.log("xは10より大きいです");
  }
}

if else文のチェーン

if…else文をチェーンすることで、複数の条件分岐を実現することができます。チェーンすることで、if…else文をネストする必要がなくなり、コードの可読性が向上します。if…else文をチェーンする場合の基本的な構文は以下のようになります。

 if (条件式1) {
   // 条件式1が真の場合に実行される処理
 } else if (条件式2) {
   // 条件式2が真の場合に実行される処理
 } else if (条件式3) {
   // 条件式3が真の場合に実行される処理
 } else {
   // どの条件も偽の場合に実行される処理
 }

最初に評価される条件式が真の場合には、その条件に対応する処理が実行されます。それ以外の場合には、次の条件式が評価されます。条件式が全て偽の場合には、elseブロックにある処理が実行されます。

以下は、if…else文をチェーンする例です。

 let score = 80;
 
 if (score >= 90) {
   console.log("秀");
 } else if (score >= 80) {
   console.log("優"); // 優と出力
 } else if (score >= 70) {
   console.log("良");
 } else if (score >= 60) {
   console.log("可");
 } else {
   console.log("不可");
 }

この例では、scoreが90以上の場合には”秀”、80以上90未満の場合には”優”、70以上80未満の場合には”良”、60以上70未満の場合には”可”、60未満の場合には”不可”というメッセージがコンソールに出力されます。

ifと論理演算子

if文では、論理演算子を使って複数の条件式を組み合わせることができます。論理演算子には、AND演算子(&&)、OR演算子(||)、NOT演算子(!)があります。

以下は、論理演算子を使用したif文の例です。

 let age = 25;
 let gender = "male";
 
 if (age >= 20 && gender === "male") {
   console.log("男性の成人です");
 }

この例では、AND演算子(&&)を使用して、ageが20以上でかつgenderが”male”である場合に、”男性の成人です”というメッセージをコンソールに出力するif文があります。この例では、ageが20以上であり、かつgenderが”male”であるため、条件が真となり、”男性の成人です”というメッセージがコンソールに出力されます。

また、OR演算子(||)を使用して複数の条件を指定することもできます。以下は、OR演算子(||)を使用したif文の例です。

 let day = "Sunday";
 
 if (day === "Saturday" || day === "Sunday") {
   console.log("週末です");
 }

この例では、OR演算子(||)を使用して、dayが”Saturday”または”Sunday”である場合に、”週末です”というメッセージをコンソールに出力するif文があります。この例では、dayが”Sunday”であるため、条件が真となり、”週末です”というメッセージがコンソールに出力されます。

NOT演算子(!)を使用して、条件を否定することもできます。以下は、NOT演算子(!)を使用したif文の例です。

let isRainy = true;

if (!isRainy) {
  console.log("晴れです");
} else {
  console.log("雨です");
}

この例では、NOT演算子(!)を使用して、isRainyがfalseである場合に、”晴れです”というメッセージをコンソールに出力するif文があります。この例では、isRainyがtrueであるため、否定され、”雨です”というメッセージがコンソールに出力されます。

switch文

以下が、switch文の基本的な構文です。

let color = "blue";

switch (color) {
  case "red":
    console.log("The color is red.");
    break;
  case "green":
    console.log("The color is green.");
    break;
  case "blue":
    console.log("The color is blue.");
    break;
  default:
    console.log("The color is not red, green, or blue.");
}

このコードでは、変数colorに代入された値を調べ、それに応じて適切なメッセージを表示しています。switch文は、caseの値とcolorの値が一致する場合、そのcaseのコードが実行されます。ここではcolorの値が”blue”に一致するため、”The color is blue.”がコンソールに表示されます。

defaultでは、どのcaseにも一致しない場合に実行される処理を指定することができます。上記の例では、colorが”red”、”green”、または”blue”のどれにも一致しない場合に”default”の処理が実行されます。

switch文は、複数の条件分岐を行う場合に便利な構文です。また、caseの値は厳密等価演算子(===)で比較されるため、型の一致も正確に比較されます。

breakとフォールスルー

switch文では、通常、caseブロックの実行が完了するとswitch文から抜けます。しかし、caseブロックの実行を完了せず、次のcaseブロックを実行することができるフォールスルーと呼ばれる機能があります。また、break文を使用することで、明示的にcaseブロックの実行を中断してswitch文から抜けることができます。

以下は、switch文でのフォールスルーとbreak文の例です。

 let num = 2;
 
 switch (num) {
   case 1:
     console.log("The number is 1");
   case 2:
     console.log("The number is 2");
   case 3:
     console.log("The number is 3");
     break;
   default:
     console.log("The number is not 1, 2, or 3");
 }

このコードでは、変数numに代入された値に応じて、適切なメッセージを表示しています。ここでは、numが2に一致するため、以下のメッセージがコンソールに表示されます。

 The number is 2
 The number is 3

case 2のブロックでメッセージが表示された後、break文がないため、次のcase 3のブロックも実行されます。これがフォールスルーです。

しかし、case 3のブロックにはbreak文が含まれているため、ブロックの実行が完了した後にswitch文から抜けます。このように、break文を使用することで、switch文からの脱出を明示的に指示することができます。

注意すべきは、フォールスルーは意図的に行う必要がある場合を除いて、一般的には避けるべきです。なぜなら、意図しない結果を引き起こすことがあるためです。明示的なbreak文を使うことで、処理の流れがわかりやすくなり、バグを防ぐことができます。

繰り返し処理

while文

while文は、指定された条件がtrueの間、繰り返し実行される制御構造です。以下は、while文の基本的な構文です。

 while (条件式) {
   // 繰り返したいコード
 }

条件式がtrueである間は繰り返し実行され続けます。繰り返し処理が実行されるたびに、条件式が再評価され、falseが返されるとループを抜けます。

例えば、以下のコードは、0から4までの数値を出力します。

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

このコードでは、変数iを初期化し、whileループ内でiが5未満の場合、iを出力し、iを1増やします。この処理を繰り返すことで、0から4までの数値が出力されます。

while文は、for文と同様に、繰り返し処理が終了しない無限ループに注意してください。適切な条件を指定することが重要です。

break文とcontinue文とlabel文

whileループでは、breakおよびcontinue文を使用して、ループの実行を制御できます。break文は、ループから抜け出すために使用されます。ループ内で特定の条件が満たされた場合、ループを強制的に終了させることができます。以下は、whileループ内でbreak文を使用する例です。

 let i = 0;
 while (i < 5) {
   if (i === 3) {
     break;
   }
   console.log(i);
   i++;
 }

このコードでは、iが3になると、break文が実行され、ループが終了します。従って、出力は0、1、2になります。

一方、continue文は、ループ内の現在のイテレーションをスキップし、次のイテレーションに進むために使用されます。以下は、whileループ内でcontinue文を使用する例です。

 let i = 0;
 while (i < 5) {
   i++;
   if (i === 3) {
     continue;
   }
   console.log(i);
 }

このコードでは、iが3の場合、continue文が実行され、ループ内の残りのコードがスキップされます。従って、出力は1、2、4、5になります。

label文とは、break文やcontinue文と組み合わせて、複雑な制御構造を持つループから簡単に抜け出すために使用されます。while文でlabelを使う場合、while文の外側のブロックにジャンプすることができます。

以下は、whileループでlabelを使う基本的な構文です。

 label: while (condition) {
   // ループ内の処理
   if (someCondition) {
     break label;
   }
 }

上記のコードでは、labelというラベル名を付けたwhileループを定義しています。ループ内でbreak label文が実行されると、ラベル名で指定されたwhileループから抜けます。

以下は、実際の例です。

 let i = 0;
 outerloop: while (i < 5) {
   console.log("outerloop: " + i);
   innerloop: while (i < 3) {
     console.log("innerloop: " + i);
     if (i === 1) {
       break outerloop;
     }
     i++;
   }
   i++;
 }

上記のコードでは、2つのwhileループを入れ子にしています。内側のループでiが1になった場合、break outerloop文が実行され、外側のループから抜けます。

上記のコードを実行すると、以下のような出力が得られます。

 outerloop: 0
 innerloop: 0
 innerloop: 1

しかし、ラベルを使う場合はコードが複雑になることがあるため、可能な場合は別の方法を検討することをお勧めします。

for文

for文は、ある条件が成り立つ間、繰り返し処理を実行するための制御構文です。以下は、for文の基本構文です。

 for (初期化式; 条件式; 更新式) {
   // 繰り返し実行する処理
 }

この構文には、以下の要素が含まれます。

  • 初期化式: 繰り返し処理が始まる前に、一度だけ実行される式です。通常は、カウンタ変数の初期化を行います。

  • 条件式: 繰り返し処理が実行されるたびに評価され、その結果がtrueである限り、繰り返し処理が継続されます。

  • 更新式: 繰り返し処理が実行されるたびに、一度だけ実行される式です。通常は、カウンタ変数の値を変更します。

以下は、for文の例です。1から10までの数字を順に表示する処理です。

 for (let i = 1; i <= 10; i++) {
   console.log(i);
 }

この場合、初期化式で変数iに1を代入し、条件式でiが10以下であるかをチェックし、更新式でiに1を加算しています。結果として、1から10までの数字が順に表示されます。

break文とcontinue文とlabel文

for文の中でbreak文やcontinue文を使用することもできます。break文は、for文やwhile文などの繰り返し処理の中で使用され、処理を中断して繰り返しを終了するために使われます。以下は、for文でbreak文を使用する例です。

 for (let i = 1; i <= 10; i++) {
   if (i === 5) {
     break;
   }
   console.log(i);
 }

この場合、iが5のときにbreak文が実行され、for文が中断されます。結果として、1から4までの数字が順に表示されます。

continue文は、for文やwhile文などの繰り返し処理の中で使用され、現在の周回を中断して、次の周回に進むために使われます。以下は、for文でcontinue文を使用する例です。

 for (let i = 1; i <= 10; i++) {
   if (i % 2 === 0) {
     continue;
   }
   console.log(i);
 }

この場合、iが偶数のときにcontinue文が実行され、次の周回に進みます。結果として、1、3、5、7、9の数字が順に表示されます。

for文でlabel文を使用するには、以下のようにラベルをfor文の前に指定します。

 label: for (初期化式; 条件式; 更新式) {
   // 処理
 }

上記のコードでは、labelというラベルをfor文の前に指定しています。このようにラベルを指定することで、内側のループから外側のループに制御を移すことができます。

以下は、for文でラベルを使用する例です。

 labelName: for (let i = 0; i < 5; i++) {
   for (let j = 0; j < 5; j++) {
     if (i === 2 && j === 2) {
       break labelName;
     }
     console.log(`i: ${i}, j: ${j}`);
   }
 }

上記の例では、2重のforループの内側のループで、iとjの値を出力しています。外側のループにラベルlabelNameが付けられています。

内側のループのif文で、iとjがともに2になったときに、break文によってラベルlabelNameが付けられた外側のループを抜け出しています。このように、labelを使用することで、複雑な制御構造を持つループから簡単に抜け出すことができます。

ただし、labelを使ったコードは読みにくくなる可能性があるため、できるだけ簡単な制御構造でコードを書くことが推奨されます。

for文と配列を組み合わせる

配列とは、複数の値を1つの変数に格納するためのデータ型です。以下は、配列の定義の例です。

 const fruits = ['apple', 'banana', 'orange'];

この場合、fruitsという配列変数に、’apple’、’banana’、’orange’という3つの文字列が格納されます。

for文を使用して、配列の要素を順番に処理することができます。以下は、配列を利用したfor文の例です。

 const fruits = ['apple', 'banana', 'orange'];
 
 for (let i = 0; i < fruits.length; i++) {
   console.log(fruits[i]);
 }

この場合、for文の条件式で、iが配列の長さより小さい限り、繰り返し処理が継続されます。iは0から始まり、1ずつ増加していきます。配列の要素は、配列変数に対して添字を指定することで、1つずつ取り出すことができます。

結果として、’apple’、’banana’、’orange’が順に表示されます。

for…in文

for…in文は、オブジェクトのプロパティ名を列挙するために使われます。以下は、for…in文の基本的な構文です。

 for (const 変数名 in オブジェクト) {
   // 処理
 }

例えば、以下のようなオブジェクトがあるとします。

 const person = {
   name: 'Taro',
   age: 30,
   gender: 'male'
 };

この場合、for…in文を使って、personオブジェクトのプロパティ名を列挙することができます。以下は、for…in文を使った例です。

 const person = {
   name: 'Taro',
   age: 30,
   gender: 'male'
 };
 
 for (const key in person) {
   console.log(key);
 }

この場合、for…in文でpersonオブジェクトのプロパティ名を取得し、key変数に格納します。結果として、’name’、’age’、’gender’が順に表示されます。

また、for…in文を使って、オブジェクトのプロパティにアクセスすることもできます。以下は、for…in文を使った例です。

 const person = {
   name: 'Taro',
   age: 30,
   gender: 'male'
 };
 
 for (const key in person) {
   console.log(`${key}: ${person[key]}`);
 }

この場合、for…in文でpersonオブジェクトのプロパティ名を取得し、key変数に格納します。そして、key変数を使って、personオブジェクトのプロパティにアクセスし、値を表示します。結果として、’name: Taro’、’age: 30’、’gender: male’が順に表示されます。

for…of文

for…of文は、配列や文字列など、反復可能なオブジェクトの要素を順番に取り出すために使われます。以下は、for…of文の基本的な構文です。

 for (const 要素 of 反復可能なオブジェクト) {
   // 処理
 }

例えば、以下のような配列があるとします。

 const fruits = ['apple', 'banana', 'orange'];

この場合、for…of文を使って、fruits配列の要素を順番に取り出すことができます。以下は、for…of文を使った例です。

 const fruits = ['apple', 'banana', 'orange'];
 
 for (const fruit of fruits) {
   console.log(fruit);
 }

この場合、for…of文でfruits配列の要素を取り出し、fruit変数に格納します。結果として、’apple’、’banana’、’orange’が順に表示されます。

また、文字列に対してもfor…of文を使うことができます。以下は、文字列を使ったfor…of文の例です。

 const str = 'hello';
 
 for (const char of str) {
   console.log(char);
 }

この場合、for…of文でstr文字列の文字を取り出し、char変数に格納します。結果として、’h’、’e’、’l’、’l’、’o’が順に表示されます。

for…of文は、配列や文字列の要素を順番に取り出すだけでなく、MapやSetといったオブジェクトに対しても使うことができます。

 const myMap = new Map();
 myMap.set('key1', 'value1');
 myMap.set('key2', 'value2');
 myMap.set('key3', 'value3');
 
 for (const [key, value] of myMap) {
   console.log(`${key}: ${value}`);
 }

上記のコードでは、Mapオブジェクトを作成し、3つのキーと値のペアを設定しています。その後、for…of文を使用してMapの各要素にアクセスし、それらをキーと値のペアとして抽出し、コンソールに出力しています。

 const mySet = new Set();
 mySet.add('apple');
 mySet.add('banana');
 mySet.add('orange');
 
 for (const fruit of mySet) {
   console.log(fruit);
 }

上記のコードでは、Setオブジェクトを作成し、3つの要素を追加しています。その後、for…of文を使用してSetの各要素にアクセスし、それらをコンソールに出力しています。

for…of文を使用することで、MapやSetの要素に順番にアクセスすることができます。

例外処理

例外処理は、プログラムが実行される際に予期せぬエラーが発生する可能性がある場合に重要です。以下は、例外処理の重要な理由です。

  1. プログラムの安定性を保つため:プログラムがエラーをスローした場合、アプリケーション全体がクラッシュする可能性があります。例外処理を使用することで、プログラムは安定性を維持し、継続的な動作を維持できます。

  2. デバッグを容易にするため:エラーが発生した場合、デバッグ情報を提供するために例外がスローされます。これにより、問題の特定と修正が簡単になります。

  3. ユーザーエクスペリエンスの向上:プログラムが予期しないエラーをスローすることは、ユーザーの不便や混乱を引き起こす可能性があります。例外処理を使用することで、ユーザーにエラーの説明や適切なアクションを提供することができます。

  4. コードの品質を高める:例外処理を使用することで、プログラムの安全性や信頼性が向上し、コードの品質が高まります。

  5. 安全性を確保するため:例外処理を使用することで、プログラムが攻撃に対して耐性を持つことができます。エラーがスローされた場合、攻撃者はプログラムを悪用する可能性があるため、例外処理は安全性を確保するための重要な機能です。

例外処理は、try-catch文を使用して実装されます。以下は、基本的な例外処理の書き方です。

try {
  // エラーが発生する可能性があるコード
} catch (error) {
  // エラーが発生した場合の処理
}

上記のコードでは、tryブロック内にエラーが発生する可能性があるコードを配置します。catchブロックでは、エラーが発生した場合に実行される処理を記述します。エラーの種類によって異なるcatchブロックを使用することができます。以下は、特定のエラーに対するcatchブロックの例です。

try {
  // エラーが発生する可能性があるコード
} catch (error) {
  if (error instanceof TypeError) {
    // TypeErrorが発生した場合の処理
  } else if (error instanceof RangeError) {
    // RangeErrorが発生した場合の処理
  } else {
    // その他のエラーが発生した場合の処理
  }
}

また、finallyブロックを使用して、try-catch文の後に実行する処理を記述することができます。以下は、finallyブロックを使用した例です。

finallyは、tryブロック内で開始した何らかの処理の後始末を記述します。例えば、ファイルを開き何かを記述する処理を実装するとします。そのためにはファイルを開き、記述し、閉じるでしょう。しかし、記述のタイミングで何らかのエラー(例外)が発生した場合、ファイルが開いたままの状態になってしまいます。開いたファイルを閉じる処理は、ファイルを開いた段階で必ず必要になるため、閉じる処理はfinallyブロックに記述しておけば、仮に記述でエラーが発生してもファイルは正常に閉じられます。

finallyは開始の処理と、終了の処理が対になっている場合に使用を検討するとよいでしょう。

 try {
   // エラーが発生する可能性があるコード
 } catch (error) {
   // エラーが発生した場合の処理
 } finally {
   // try-catch文の後に実行する処理
 }

さらに、throw文を使用して、自分で例外をスロー(投げる)することもできます。以下は、throw文を使用した例です。

 try {
   // 条件が満たされない場合に例外をスローする
   if (x < 0) {
     throw new Error('xは0以上である必要があります。');
   }
 } catch (error) {
   // エラーが発生した場合の処理
 }

上記のコードでは、xが0未満の場合に、throw文を使用することで、自ら例外をスローしています。スローされた例外はcatchブロックでキャッチされます。

コメント

タイトルとURLをコピーしました