2022 年 4 月 25 日

“switch” 语句

一个 switch 语句可以替换多个 if 检查。

它提供了一种更具描述性的方式来将一个值与多个变量进行比较。

语法

switch 有一个或多个 case 块和一个可选的默认值。

它看起来像这样

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

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

  default:
    ...
    [break]
}
  • x 的值将与第一个 case(即 value1)中的值进行严格相等检查,然后与第二个(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 从第一个 case 变体(即 3)开始比较 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" );
}

在上面的示例中,我们将看到三个 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");
}

此处,+a 给出 1,它与 case 中的 b + 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 都显示相同的消息。

能够对 case 进行“分组”是 switch/case 在没有 break 的情况下工作方式的副作用。此处,case 3 的执行从第 (*) 行开始,然后遍历 case 5,因为没有 break

类型很重要

让我们强调一下,相等性检查始终是严格的。值必须具有相同的类型才能匹配。

例如,我们考虑以下代码

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,第二个 alert 运行。
  3. 但对于 3prompt 的结果是一个字符串 "3",它与数字 3 不严格相等 ===。因此,我们在 case 3 中得到了一个死代码!default 变体会执行。

任务

重要性:5

编写使用 if..else 的代码,它对应于以下 switch

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' );
}

前两个检查变为两个case。第三个检查被拆分为两个 case

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,例如case 4。如果我们忘记在case 3末尾添加一个 break,将会出现一个错误。所以这是一种自我保险。

教程地图

评论

在评论之前阅读此内容…
  • 如果您有改进建议 - 请提交 GitHub 问题或提交拉取请求,而不是评论。
  • 如果您无法理解文章中的某些内容 - 请详细说明。
  • 要插入几行代码,请使用<code>标签,对于多行 - 将它们包装在<pre>标签中,对于 10 行以上 - 使用沙箱 (plnkrjsbincodepen…)