【ES6】初识块级作用域

171 阅读2分钟

块级作用域

作用域原本包含全局作用域函数作用域。现在ES6带来了块级作用域

变量提升

平时我们都是通过 var 来声明变量,每当我们使用 var 时都会涉及到变量提升。什么是变量提升呢?我们先来看一段代码。

console.log(a) //undefined
var a = 'JavaScript'
console.log(b) //b is not defined

我们可以看到此时打印 a 是不会报错的。其实一个变量是分为声明赋值两部分的,引擎在正式执行代码之前会进行一次预编译,此时变量会被提前存到内存中。所以第一个 a 会打印 undefined。基础的变量提升就是这样。

let和const

因为变量提升的存在,代码的执行会出现不按顺序的情况。块级作用域能较好的解决这个问题,其实块级作用域的作用就是代码写在哪,就在哪里执行,定义在代码块中的变量在代码块执行结束后会被销毁掉。ES6中的 letconst 就是拿来实现块级作用域的。

let 和 const 的用法var的使用方法类似。不过他们声明的变量不存在变量提升,且只能起作用在特定代码块。

   console.log(a) //a is not defined
   let a = 'JavaScript'
   
   console.log(a) //a is not defined
   const a = 'JavaScript'
   
   function foo()
      {
        if(true){
            let a = 'aaa'
            console.log(a)
        }
         console.log(a)
      }
       
    function bar()
       {
         if(true){
           var b = 'bbb'
           console.log(b)
        }
         console.log(b)
      }
      
      bar() // bbb  bbb
      foo() // aaa  a is not defined
      
      
    function foz()
       {
         if(true){
            const c = 'ccc'
            console.log(c)
        }
         console.log(c)
      } 
      foz() //ccc  c is not defined

注意虽然 let 和 const 很像,但他们还是有区别的。const 声明的是常量,常量是不能被更改的。但是 const 声明的对象的内部的值是可以被修改的,不过指针所指向的地址是不能被改变的。

const a = 'aaa'; 
a = 'bbb'; // TypeError: Assignment to constant variable.

let a = 'aaa'
a = 'bbb'
console.log(a) //bbb

const person = {
    name:'张三',
    age:20
}
person.name = '李四'
console.log(person) //{ name: '李四', age: 20 }

同样需要注意的是,let 和 const 不能重复声明。下面是几个基础例子。

let a = 'aaa'
let a = 'bbb' //'a' has already been declared

let a = 'aaa'
const a = 'bbb' //'a' has already been declared

let a = 'aaa'
var a = 'bbb' //'a' has already been declared

思考

我们可以知道在ES6面世之前是没有块级作用域这一说法的,那么块级作用域是如何实现的呢?变量提升又是如何实现的呢?