switch 语句中的块级作用域

问题背景:

最近在公司业务代码中,根据switchcase判断任务类型,在 case 里面定义了块级变量,但是 eslint校验有问题,不同 case 语句中的变量重复定义,以及前面的 case 定义的变量,在后面的case中也能访问到。

目标:

研究switch语句中的块级作用域可能存在的问题

switch语句中的块级作用域

switch语句中的块级作用域,在整个switch语句中,而不是对于每一个case生成一个独立的块级作用域。

下面来举几个例子来说明这个问题:

let number = 1;
switch(number){
  case 1:
    let name = 'Jony';
  default:
    console.log(name)
}

上述的代码会输出jony。

再看一个例子:

let number = 1;
switch(number){
  case 1:
    let name = 'Jony';
    break;
  case 2:
    let name = 'yu';
    break;
  default:
  console.log(name);
}

这样会在重复声明的错误:

Uncaught SyntaxError: Identifier 'name' has already been declared

上述两个例子说明确实switch语句中,整个switch语句构成一个块级作用域。而与case无关,每一个case并不会构成一个独立的块级作用域。

根据经MDN提供的解决方案,可以添加 花括号{}生成一个单独的块级作用域,所以上述例子可以改成:

let number = 1;
switch(number){
  case 1: {
    let name = 'Jony';
    break;
  }
  case 2: {
    let name = 'yu';
    break;
  }
  default: {
    console.log(name);
  }
}

现在的结果就是输出 undefiend

switch语句中的块级作用域可能存在的问题

let number = 2;
switch(number){
  case 1:
    let name = 'jony';
    break;
  case 2:
    name = 'yu';
    break;
}

这个例子中,会报错,会报name未定义的错误。

Uncaught ReferenceError: name is not defined

原因的话,这里虽然case里面定义的块级虽然不会存在变量提升,但是会存在暂时性死区,也就是说如果let name = 'jony' 没有执行,也就是name定义的过程没有执行,那么name在整个块级作用域内都是不可用的,都是undefined

总结

  • 对于重复使用的变量最好定义在 switch 语法外
  • 对于不重复使用的变量,需要在case里声明一个{}块级作用域

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦