黄子涵

4.13 switch-case语句

switch-case 语句是一种语法结构与 if-else 有所不同的条件分支判断语句。其语法结构如下。

// switch-case 语句的语法
switch ( 语句 ) {
case 表达式 1:
语句
语句
......
case 表达式 2:
语句
语句
......
case 表达式 N:
语句
语句
......
default:
语句
语句
......
}

根据习惯,“case 表达式:”部分被称为 case 标签,而 “default:” 部分被称为 default 标签。从语法规则的角度来看,它们与 if-else 语句中子句的功能不同,起到的是跳转目标的作用。在 switch 语句中可以书写多个 case 标签,而 default 标签则只能使用 1 次。此外,default 标签是可以省略的。

尽管 JavaScript 中的 switch 语句在语法结构上与 Java 的相同,但它们在实际的语法规则上却有着一些细微的差异。在 JavaScript 中,switch 的括号内可以写任意类型的表达式,case 标签中也可以写任意的表达式。与之相对应地,在 Java 的 case 标签中,则只能使用在编译时就能够获得结果的常量表达
式。

switch 语句会把其在 switch 之后的括号内的表达式,与 case 标签中所写的各个表达式,依次通过相等运算符(===)进行比较。为了避免用词混淆,这里将前者称为 switch 表达式,而将后者称为 case 表达式。=== 运算符是不会进行数据类型转换的相等运算符。switch 语句首先对 switch 表达式进行求值,之后依次对 case 表达式从上往下求值,并将其结果与 switch 表达式的求值结果进行等值比较(===)。如果值相等,则跳转至该 case 标签处。如果与所有的 case 表达式都不等值,则跳转至 default 标签处。

下面的例子主要展示了一些在 Java 中不被允许的类型。

代码清单 4.1 switch语句的例子

var hzh = '黄子涵';
switch (hzh) { // 可以在switch表达式中使用字符串值
// 可以在case表达式中使用和switch表达式类型不同的值
// hzh === 0 的值,所以将继续进行比较
case 0:
console.log("不在这里");
break;
// 可以在case表达式中使用含有变量的表达式
// hzh === hzh.length 的值为假,所以继续进行比较
case hzh.length:
console.log("不在这里");
break;
// 可以在 case 表达式中使用方法调用表达式
// s === (0).toString()的值为假,所以将继续进行比较
case (0).toString():
console.log("不在这里");
// 还可以在case表达式中书写这样的表达式
// hzh === '黄' + '子' + '涵'为真,所以执行以下的代码
case '黄' + '子' + '涵':
console.log('在这里');
break;
// 如果所有的case表达式在等值运算(===)后得到的结果都为假,则执行以下的代码
default:
console.log('不在这里');
break;
}
[Running] node "e:\HMV\Babel\hzh.js"
在这里
[Done] exited with code=0 in 1.498 seconds

一看,case 标签之间的部分是作为一个整体来执行的,不过实际上,case 标签并没有对代码按块进行分割的功能。因此在一个 case 标签结束执行之后,并不会跳出 switch 语句。

在代码清单 4.2 的 switch 语句中,虽然第一个 case 标签的比较结果就为真,但之后所有的 case 标签也都会被执行。

代码清单 4.2 没有 break 语句的 switch 语句,将不会在执行完其中某一段 case 之后就结束整个 switch 语句

var hzh = 0;
switch (hzh) {
case 0:
console.log('黄子涵是帅哥!');
case 1:
console.log('黄子涵是靓仔!');
case 2:
console.log('黄子涵真聪明!');
case 3:
console.log('黄子涵真厉害!');
default:
console.log('黄子涵');
break;
}
[Running] node "e:\HMV\JavaScript\JavaScript.js"
黄子涵是帅哥!
黄子涵是靓仔!
黄子涵真聪明!
黄子涵真厉害!
黄子涵
[Done] exited with code=0 in 2.271 seconds

由这一结果可知,应该将 case 标签与 default 标签看作跳转的目标地址。也就是应该这样来理解 case 标签的作用:当 switch 表达式与 case 表达式的值相一致时,就跳至该 case 标签所在位置,执行完该段代码之后继续从上往下逐次执行后续语句。

在很多时候,上面这样的代码都无法得到预期的结果。像代码清单 4.3 这样使用 break 语句就可以强制跳出当前 switch 语句。

代码清单 4.3 通过 break 语句跳出 switch 语句

var hzh = Math.round(Math.random()*10);
switch (hzh) {
case 0:
console.log('黄子涵是帅哥!');
break;
case 1:
console.log('黄子涵是靓仔!');
break;
case 2:
console.log('黄子涵真聪明!');
break;
case 3:
console.log('黄子涵真厉害!');
break;
case 4:
console.log('我是你爹!');
break;
case 5:
console.log('我是你妈!');
break;
case 6:
console.log('我是你爷!');
break;
case 7:
console.log('黄子涵比彭于晏帅!');
break;
case 8:
console.log('黄子涵比尤雨溪聪明!');
break;
default:
console.log('黄子涵');
break;
}

image

如果在 if-else 语句中有多个连续的分支判断,则可以将代码改写为等价的 switch 语句。在两种写法都可以的情况下,具体选择哪一种只是偏好问题,认为哪一种方式的可读性更好就选择哪一种即可。根据情况不同,有时比起 if-else 语句,switch语句的可读性会更好(这样说可能带有一些主观偏好)。至少在使用 switch 语句时,等值比较表达式可以被隐藏起来,所以与使用了等值比较的 if-else 语句相比表达上更为简洁。需要注意的是,switch 语句所隐藏的等值比较运算是不会对数据类型进行转换的 === 运算。如果原来的 if-else 语句中的表达式使用的是 == 运算的话,就可能会在执行上有一些细微的差别。而这样的问题通常不容易被发现,很容易成为产生错误的根源。

posted @   黄子涵  阅读(514)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示