先看下暂时性死区的例子
let a = 1 if (true) { console.log(a) let b = 2 } //输出1 let a = 1 if (true) { console.log(a) let a = 2 } //Uncaught ReferenceError:Cannot access 'me' before initialization为什么会出现这种情况呢?这就是我们今天要了解的js中的暂时性死区( temporal dead zone,简称TDZ );
先看关于ES6标准中关于暂时性死区的解释:
The variables are created when their containing Lexical Environment is instantiated but may not be accessed inany way until the variable’s LexicalBinding is evaluated.翻译过来的意思就是:
当程序的控制流程在新的作用域(module function 或 block作用域)进行实例化时,在此作用域中用let/const声明的变量会先在作用域中被创建出来, 但因此时还未进行词法绑定,所以是不能被访问的,如果访问就会抛出错误。因此,在这运行流程进入作用域创建变量,到变量可以被访问之间的这一段时间,就称之为暂时死区。简单来说就是:如果区块中存在 let 和 const 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。假如我们尝试在声明前去使用这类变量,就会报错
JS 和其他语言一样,都要经历编译和执行阶段。正是在这个短暂的编译阶段里,JS 引擎会搜集所有的变量声明,并且提前让声明生效。至于剩下的语句,则需要等到执行阶段、等到执行到具体的某一句的时候才会生效。这就是变量提升背后的机制。所以其实let也有提升,使用es6的参数初始化,参数的声明都提升了,会提升的块级作用域顶部,但是提升了却没有初始化,但是var变量提升会初始化为undefined,所以还可以使用,但是let没有初始化,所以在【提前的声明】到【声明初始化】的地方就是暂时性死区,也就是不能在这区间使用这个提升的但没有初始化let变量