大多數(shù)語(yǔ)言的 switch 語(yǔ)句的語(yǔ)法和特性都是一樣的,但是 JavaScript 語(yǔ)言中的 switch 語(yǔ)句有些特性比較特別,如果你了解其它的編程語(yǔ)言,你甚至?xí)X(jué)得這些特性更像是 JavaScript 的bug,如果你不了解這些特性,當(dāng)你無(wú)意中使用到這些特性時(shí),將會(huì)給你帶來(lái)非常難以排查的問(wèn)題;
目錄
一、switch語(yǔ)句的語(yǔ)法
二、switch語(yǔ)句的穿透特性
內(nèi)容
一、switch語(yǔ)句的語(yǔ)法
switch (expression) {
case value1:
// 當(dāng) expression 的結(jié)果與 value1 匹配時(shí),執(zhí)行此處語(yǔ)句
[break;]
case value2:
// 當(dāng) expression 的結(jié)果與 value2 匹配時(shí),執(zhí)行此處語(yǔ)句
[break;]
...
case valueN:
// 當(dāng) expression 的結(jié)果與 valueN 匹配時(shí),執(zhí)行此處語(yǔ)句
[break;]
[default:
// 如果 expression 與上面的 value 值都不匹配時(shí),執(zhí)行此處語(yǔ)句
[break;]]
}
- expression : 用來(lái)與 case 子語(yǔ)句匹配的表達(dá)式。
- case valueN : 可選; 用于匹配 expression 的 case 子句。如果 expression 與給定的 valueN 相匹配,則執(zhí)行該 case 子句中的語(yǔ)句直到該 switch 語(yǔ)句結(jié)束或遇到一個(gè) break 。
- default : 可選;定義 default 子句,一個(gè) switch 語(yǔ)句 最多只能有一個(gè) default 子句;如果給定,這條子句會(huì)在 expression 的值與任一 case 語(yǔ)句均不匹配時(shí)執(zhí)行。
描述
一個(gè) switch 語(yǔ)句首先會(huì)計(jì)算其 expression 。然后,它將從第一個(gè) case 子句開(kāi)始直到尋找到一個(gè)其表達(dá)式值與所輸入的 expression 的值 嚴(yán)格相等(===)的子句,并執(zhí)行該子句的相關(guān)語(yǔ)句。如果沒(méi)有 case 子句相匹配,程序則會(huì)尋找那個(gè)可選的 default 子句,如果找到了,就執(zhí)行該 default 的相關(guān)語(yǔ)句。若沒(méi)有 default 子句,程序?qū)⒗^續(xù)執(zhí)行直到 switch 結(jié)束。一般情況下,會(huì)把 default 作為 switch 的最后一個(gè)子句,不過(guò)也可以把 default 子句放在 case 子句之間 或者 之前。
break 語(yǔ)句是可選的,它會(huì)使程序立即從相關(guān)的 case 子句中跳出 switch 語(yǔ)句塊,并接著執(zhí)行 switch 語(yǔ)句塊之后的語(yǔ)句。若 break 被省略,程序會(huì)繼續(xù)執(zhí)行 switch 語(yǔ)句中的下一條語(yǔ)句。
二、switch語(yǔ)句的穿透特性
因?yàn)椋?code>case valueN 用于匹配 expression 的 case 子句。如果 expression 與給定的 valueN 相匹配,則執(zhí)行該 case 子句中的語(yǔ)句直到該 switch 語(yǔ)句結(jié)束或遇到一個(gè) break ;
所以:如果匹配的 case 子句 中沒(méi)有 break ,則會(huì)執(zhí)行該 case 子句中的語(yǔ)句直到該 switch 語(yǔ)句結(jié)束,包括 default 子句 及 default 子句 之后的 case 子句,即使該 case 子句后面的 case 子句不匹配,也同樣會(huì)執(zhí)行;
示例:
function switchTest(value) {
switch (value) {
case 1:
console.log("case 1 子句 : default之前");
break;
case 2:
console.log("case 2 子句 : default之前");
case 3:
console.log("case 3 子句 : default之前");
break;
case 4:
console.log("case 4 子句 : default之前");
case 5:
console.log("case 5 子句 : default之前");
default:
console.log("default子句");
case 6:
console.log("case 6 子句 : default之后");
case 7:
console.log("case 7 子句 : default之后");
}
console.log("switch語(yǔ)句后面的語(yǔ)句");
}
測(cè)試1:匹配的 case 子句中有 break
switchTest(1)
輸出:
case 1 子句 : default之前
switch語(yǔ)句后面的語(yǔ)句
測(cè)試2:匹配的 case 子句中沒(méi)有 break
switchTest(2)
輸出:
case 2 子句 : default之前
case 3 子句 : default之前
switch語(yǔ)句后面的語(yǔ)句
測(cè)試3:匹配的 case 子句中沒(méi)有 break
switchTest(4)
輸出:
case 4 子句 : default之前
case 5 子句 : default之前
default子句
case 6 子句 : default之后
case 7 子句 : default之后
結(jié)論:
如果 case 子句 中及其之后沒(méi)有 break ,則會(huì)執(zhí)行該 case 子句中的語(yǔ)句直到該 switch 語(yǔ)句結(jié)束,包括 default 子句 及 default 子句 之后的 case 子句;
測(cè)試4:沒(méi)有與我匹配的case子句
switchTest("沒(méi)有與我匹配的case")
輸出:
default子句
case 6 子句 : default之后
case 7 子句 : default之后
switch語(yǔ)句后面的語(yǔ)句
結(jié)論:
如果 default 子句 中及其之后沒(méi)有 break ,則會(huì)執(zhí)行該 default 子句中的語(yǔ)句直到該 switch 語(yǔ)句結(jié)束,包括 default 子句 之后的 case 子句;
綜上所述,就有:
switch語(yǔ)句的穿透特性 (本人自定義的名字,非標(biāo)準(zhǔn)名字)
如果匹配的 switch子句 (case子句 或 default 子句) 中沒(méi)有
break,則會(huì)執(zhí)行該 switch子句 中的語(yǔ)句直到該 switch 語(yǔ)句結(jié)束,包括 default 子句 及 default 子句 之后的 case 子句,即使該 case 子句后面的 case 子句不匹配,也同樣會(huì)執(zhí)行;