原文:https://dev.to/bhagatparwinder/js-switch-statement-explained-101c
介绍
switch 是一个条件语句,根据表达式的值来执行对应的语句,可以把它想象为多分支 if 语句。
关键点
- 执行表达式
- case 块
- (可选)默认块
语法
switch (expressopm) {
case value1:
//Statements executed when the
//result of expression matches value1
break; // break from further evaluation
case value2:
//Statements executed when the
//result of expression matches value2
break;
case valueN:
//Statements executed when the
//result of expression matches valueN
break;
default:
//Statements executed when none of
//the values match the value of the expression
break;
}
例子
const tellMeTheNumber = (num) => {
switch(num) {
case 1:
console.log("You are number one!");
break;
case 2:
console.log("Second is not a bad place to be.");
break;
case 3:
console.log("Three Three Three");
break;
case 4:
console.log("Quad");
break;
default:
console.log("I don't know who I am anymore?");
break;
}
}
tellMeTheNumber(4); // Quad
tellMeTheNumber(1); // You are number one!
tellMeTheNumber(1); // I don't know who I am anymore?
省略 break 会如何?
在 switch 语句中,如果我们省略了 break 语句,所有的语句都会执行。
const tellMeTheNumber = (num) => {
switch(num) {
case 1:
console.log("You are number one!");
case 2:
console.log("Second is not a bad place to be.");
case 3:
console.log("Three Three Three");
case 4:
console.log("Quad");
default:
console.log("I don't know who I am anymore?");
break;
}
}
tellMeTheNumber(1);
// You are number one!
// Second is not a bad place to be.
// Three Three Three
// Quad
// I don't know who I am anymore?
上面的例子中虽然我们传入 1 但语句中都没有 break 关键字,但是依旧会执行 2,3,4 和 默认语句。
分组情况
在 switch 语句中若多个条件需要执行相同的动作,为了避免代码冗余我们可以把他们分组:
const tellMeTheNumber = (num) => {
switch (num) {
case 1:
case 2:
case 3:
console.log("You are in top 3");
break;
case 4:
console.log("You did not make it this time");
break;
default:
console.log("I don't know who I am anymore?");
break;
}
}
tellMeTheNumber(2); // You are in top 3
tellMeTheNumber(4); // You did not make it this time
tellMeTheNumber(12); // I don't know who I am anymore?
1,2 或 3 会输出相同的信息。
严格类型检测
switch 语句的中表达式与 case 语句的比较是 ====
比较其值同时也比较类型,所以在下面的例子中我们传入 "3"
和 3
会得到不同的结果:
const tellMeTheNumber = (num) => {
switch (num) {
case 1:
case 2:
case 3:
console.log("You are in top 3");
break;
case 4:
console.log("You did not make it this time");
break;
default:
console.log("I don't know who I am anymore?");
break;
}
}
tellMeTheNumber(3); // You are in top 3
tellMeTheNumber("3"); // I don't know who I am anymore?
因为字符串 "3"
不会匹配任何 case 所以 default 会执行。
块级作用域
ES6 或 ES2015 引入 let 和 const 来创建块级作用域,记住如果在 switch 语句中使用它们需要多加注意一些:
const action = 'say_hello';
switch (action) {
case 'say_hello':
let message = 'hello';
console.log(message);
break;
case 'say_hi':
let message = 'hi';
console.log(message);
break;
default:
console.log('Empty action received.');
}
上面的代码会报错:Uncaught SyntaxError: Identifier ‘message’ has already been declared 即使 message 在不同的 case 中声明他们依旧是属于同一个作用域所以产生了冲突。
我们只需要稍加变化,则会消除该报错:
const action = 'say_hello';
switch (action) {
case 'say_hello': { // added brackets
let message = 'hello';
console.log(message);
break;
} // added brackets
case 'say_hi': { // added brackets
let message = 'hi';
console.log(message);
break;
} // added brackets
default: { // added brackets
console.log('Empty action received.');
} // added brackets
}
注意下面两种情况:
- 移出 say_hi 中的 let 同时使用
"say_hello"
调用:
const action = 'say_hello';
switch (action) {
case 'say_hello':
let message = 'hello';
console.log(message);
break;
case 'say_hi':
message = 'hi';
console.log(message);
break;
default:
console.log('Empty action received.');
}
正常输出:hello
,
- 移出 say_hi 中 let 同时使用
"say_hi"
调用:
const action = 'say_hi';
switch (action) {
case 'say_hello':
let message = 'hello';
console.log(message);
break;
case 'say_hi':
message = 'hi';
console.log(message);
break;
default:
console.log('Empty action received.');
}
报错:Uncaught ReferenceError: Cannot access ‘message’ before initialization。