全部 / 前端 / 技术 · 2022年6月4日 0

25 – switch 语句解释说明

广告位招租 (vx: ghostcode, 备注:网站广告)

原文:https://dev.to/bhagatparwinder/js-switch-statement-explained-101c

介绍

switch 是一个条件语句,根据表达式的值来执行对应的语句,可以把它想象为多分支 if 语句。

关键点

  1. 执行表达式
  2. case 块
  3. (可选)默认块

语法

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
}

注意下面两种情况:

  1. 移出 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

  1. 移出 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

前端黑板报