2022年4月25日

switch文

switch文は、複数のifチェックを置き換えることができます。

値を複数のバリアントと比較する、より記述的な方法を提供します。

構文

switchには、1つ以上のcaseブロックと、オプションのdefaultがあります。

次のように見えます。

switch(x) {
  case 'value1':  // if (x === 'value1')
    ...
    [break]

  case 'value2':  // if (x === 'value2')
    ...
    [break]

  default:
    ...
    [break]
}
  • xの値は、最初のcase(つまり、value1)からの値、次に2番目(value2)などに対して、厳密な等価性がチェックされます。
  • 等価が見つかった場合、switchは対応するcaseから始まり、最も近いbreakまで(またはswitchの最後まで)、コードの実行を開始します。
  • どのcaseにも一致しない場合は、defaultコードが実行されます(存在する場合)。

switchの例(実行されるコードは強調表示されています)

let a = 2 + 2;

switch (a) {
  case 3:
    alert( 'Too small' );
    break;
  case 4:
    alert( 'Exactly!' );
    break;
  case 5:
    alert( 'Too big' );
    break;
  default:
    alert( "I don't know such values" );
}

ここでは、switchは、3である最初のcaseバリアントからaの比較を開始します。一致しません。

次に4。これは一致するため、実行はcase 4から最も近いbreakまで開始されます。

breakがない場合、チェックなしで次のcaseが実行されます。

breakがない例

let a = 2 + 2;

switch (a) {
  case 3:
    alert( 'Too small' );
  case 4:
    alert( 'Exactly!' );
  case 5:
    alert( 'Too big' );
  default:
    alert( "I don't know such values" );
}

上記の例では、3つのalertが連続して実行されます。

alert( 'Exactly!' );
alert( 'Too big' );
alert( "I don't know such values" );
任意の式がswitch/case引数になることができます

switchcaseの両方で、任意の式を使用できます。

例えば

let a = "1";
let b = 0;

switch (+a) {
  case b + 1:
    alert("this runs, because +a is 1, exactly equals b+1");
    break;

  default:
    alert("this doesn't run");
}

ここでは、+a1を返し、caseb + 1と比較され、対応するコードが実行されます。

「case」のグループ化

同じコードを共有するいくつかのcaseバリアントをグループ化できます。

例えば、case 3case 5で同じコードを実行したい場合

let a = 3;

switch (a) {
  case 4:
    alert('Right!');
    break;

  case 3: // (*) grouped two cases
  case 5:
    alert('Wrong!');
    alert("Why don't you take a math class?");
    break;

  default:
    alert('The result is strange. Really.');
}

これで、35の両方で同じメッセージが表示されます。

ケースを「グループ化」できるのは、breakがない場合のswitch/caseの動作方法による副作用です。ここでは、case 3の実行は(*)行から始まり、breakがないため、case 5まで続きます。

型が重要

等価性チェックは常に厳密であることを強調しておきましょう。値は、一致させるために同じ型である必要があります。

例えば、次のコードを考えてみましょう。

let arg = prompt("Enter a value?");
switch (arg) {
  case '0':
  case '1':
    alert( 'One or zero' );
    break;

  case '2':
    alert( 'Two' );
    break;

  case 3:
    alert( 'Never executes!' );
    break;
  default:
    alert( 'An unknown value' );
}
  1. 01の場合、最初のalertが実行されます。
  2. 2の場合、2番目のalertが実行されます。
  3. しかし、3の場合、promptの結果は文字列"3"であり、数値3と厳密に等しくありません(===)。そのため、case 3にはデッドコードがあります!defaultバリアントが実行されます。

課題

重要度: 5

次のswitchに対応するif..elseを使用してコードを作成してください。

switch (browser) {
  case 'Edge':
    alert( "You've got the Edge!" );
    break;

  case 'Chrome':
  case 'Firefox':
  case 'Safari':
  case 'Opera':
    alert( 'Okay we support these browsers too' );
    break;

  default:
    alert( 'We hope that this page looks ok!' );
}

switchの機能に正確に一致させるには、ifは厳密な比較'==='を使用する必要があります。

ただし、与えられた文字列の場合、単純な'=='でも機能します。

if(browser == 'Edge') {
  alert("You've got the Edge!");
} else if (browser == 'Chrome'
 || browser == 'Firefox'
 || browser == 'Safari'
 || browser == 'Opera') {
  alert( 'Okay we support these browsers too' );
} else {
  alert( 'We hope that this page looks ok!' );
}

注記: 構成browser == 'Chrome' || browser == 'Firefox' …は、可読性を向上させるために複数行に分割されています。

しかし、switch構成はまだよりクリーンで記述的です。

重要度: 4

以下のコードを単一のswitch文を使用して書き換えてください。

let a = +prompt('a?', '');

if (a == 0) {
  alert( 0 );
}
if (a == 1) {
  alert( 1 );
}

if (a == 2 || a == 3) {
  alert( '2,3' );
}

最初の2つのチェックは2つのcaseに変換されます。3番目のチェックは2つのケースに分割されます。

let a = +prompt('a?', '');

switch (a) {
  case 0:
    alert( 0 );
    break;

  case 1:
    alert( 1 );
    break;

  case 2:
  case 3:
    alert( '2,3' );
    break;
}

注記: 最下部のbreakは必須ではありません。ただし、コードを将来対応できるようにするために追加しました。

将来、例えばcase 4のように、もう1つのcaseを追加したい可能性があります。そして、case 3の最後にbreakを追加するのを忘れると、エラーが発生します。そのため、一種の自己保険です。

チュートリアルマップ

コメント

コメントする前にこれを読んでください…
  • 改善点の提案がある場合は、コメントする代わりにGitHub issueまたはプルリクエストを送信してください。
  • 記事の内容が理解できない場合は、詳しく説明してください。
  • 数語のコードを挿入するには<code>タグを使用し、複数行の場合は<pre>タグで囲み、10行以上の場合にはサンドボックス(plnkrjsbincodepen…)を使用してください。