# 【JavaScript进阶】Switch/Case和块级作用域

# 一、先看代码

  • 1.switch-case-01

    执行这段代码的话就会报错:

    Uncaught SyntaxError: Identifier 'b' has already been declared

    意为b已经被声明过了,无法重复声明。

  • 2.解决问题的话也简单,使用var代替const就好了。

    switch-case-03

  • 3.但是如果不想用var呢?可以这样:👇

    switch-case-02

可以看出,const关键字只在代码块{}内部有效,这个代码块就是一个块级作用域,而var关键字声明的变量在这里由于变量提升,它在这里定义的其实是一个全局变量,代码等同于:

 




 





 





var b;
let a = 1;

switch (a) {
  case 1:
    b = a;
    console.log(b);

    break;

  case 2:
    b = a;
    console.log(b);

    break;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 二、块级作用域

在ES6之前,JavaScript中只有全局作用域函数作用域。ES6的新特性中引入了letconst关键字,以及块级作用域

先看letconst:👇

  • 使用letconst声明的变量不会成为全局变量

  • 它们声明的变量在同一作用域中不能被二次声明

    {
      let a = 1;
      const b = "b";
    
      let a = 2;// 错误,不能重复声明
      const b = "c";// 错误,不能重复声明和赋值
    }
    
    1
    2
    3
    4
    5
    6
    7
  • 它们声明的变量只能在当前块级作用域中访问,不能跨块访问

    {
      let a = 1;
    }
    console.log(a);// undefined
    
    1
    2
    3
    4
  • 使用const声明的变量不能被修改,即常量,并且声明时必须赋值

    其实对象内部的属性值还有数组内部的值是可以修改的,但对象不能增删属性

接着看块级作用域

  • 一个{}就是一个块级作用域;

  • if语句和for语句中的{}也属于块级作用域;

  • 块级作用域可以一直嵌套;

  • 块级作用域没有返回值

  • 外部作用域无法获取/操作内部作用域的变量

    {
      {
        let a = 1;
      }
      console.log(a);// undefined
    }
    
    1
    2
    3
    4
    5
    6
  • 内部作用域可以获取/操作外部作用域的变量

    {
      let a = 1;
      {
        a = 2;
        console.log(a);// 2
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
  • 内部作用域可以定义外部作用域同名变量

    {
      let a = 1;
      {
        let a = 2;
      }
    }
    
    1
    2
    3
    4
    5
    6
  • 块级作用域内部可以声明函数,但在严格模式下,必须要有{}存在;

    // 错误
    'use strict';
    if (true) function fn(){}
    // Uncaught SyntaxError: In strict mode code, functions can only be declared at top level or inside a block.
    
    // 正确
    'use strict';
    if (true) {
      function fn() {}
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
Last Updated: 2 years ago