作用域
- 全局作用域中的对象在代码中的任何地方都能访问,其生命周期伴随着页面的生命周期。
- 函数作用域就是在函数内部定义的变量或者函数,并且定义的变量或函数只能在函数内部访问,函数执行结束后,函数内部定义的变量会被销毁。
- 块级作用域就是使用一对大括号包裹的一段代码,比如函数、判断语句、循环语句甚至是单独的一个{}都会被是为一个块级作用域,JS在ES6之后引入块级作用域。
变量提升所带来的问题
- 变量容易在不被察觉的情况下被覆盖掉:JS在执行上下文时,先使用函数执行上下文里面的变量。
- 本应销毁的变量没有被销毁:函数内部的变量被全局提升,导致未被销毁。
ES6是如何解决变量提升带来的缺陷
- ES6引入let和const关键字,使JS拥有块级作用域。
- let关键字声明的变量可以修改,const关键字声明的变量不可修改。两者都生成块级作用域。
- 块级作用域可以把内部变量限制在作用域内部,而不会被变量提升到上级或全局的变量环境中。
- JS是如何支持块级作用域的
- 在编译阶段,var声明的变量,会被存放到变量环境里面。
- let 声明的变量会被存放到词法环境的一个单独的区域中
- 在词法环境内部,维护了一个小型栈结构,栈底是函数最外层的变量,栈顶为块级作用域内部的变量(let 和 const 声明),当作用域执行完成后,从栈顶弹出。
- 执行上下文时,先从词法环境的栈顶向下查询,如果未查找到,则去变量环境中查找。
- 块级作用域时用过词法环境的栈结构来实现的。变量提升是通过环境变量来实现的。两者结合,JS引擎就能同时支持变量提升和块级作用域了。