变量提升 和 暂时性死区
变量提升
ES6 明确规定,如果区块中存在 let 和 const 命令,那么就会形成封闭作用域。凡是在声明之前使用这些变量,就会报错。
也就是说,let、const 声明的变量,不会存在变量提升,而 var 会
var a = 100
if (true) {
a = 999
console.log(a);
let a
}
会报错:Cannot access 'a' before initialization
什么是暂时性死区?
当程序的控制流程在新的作用域进行实例化时,在此作用域中的let/const声明的变量,会先在作用域中创建出来,但此时还未在词法环境中进行注册(没有词法绑定),则此时是不能被访问的,访问就会报错。
从创建变量到可以被访问这一期间,叫做暂时性死区。
let、const、import、class、typeof都会出现暂时性死区
var、function不会出现暂时性死区
暂时性死区究其原因还是没有先声明后使用,解决办法就是要先声明后使用,否则就会引发暂时性死区
暂时性死区的本质是:只要一进入当前作用域,所使用的变量就已经存在了,但是不可获取。只有等到 let、const 声明变量的那一行代码出现,才能获取和使用该变量
忍者秘籍中的解释:
变量提升(variable hoisting):var 变量和函数的声明并没有发生实际移动,只是在代码执行之前,先在词法环境中进行注册(注册就是 let a 的意思)
词法环境:人们通常称为作用域,有全局环境、函数环境、块级环境
- 通过 var 声明的变量总是在距离最近的 函数内或全局词法环境 中进行注册,不关注块级作用域
- let 和 const 在最近的词法环境中进行注册(可以是块级作用域、函数作用域、全局作用域)
这一路,灯火通明