
原文: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。



 
																								