temporal dead zone

使用var声明变量

在es6定义let和const声明符之前,我们声明一个变量通常使用var:

1
var a = 1

我们可以在变量被声明之前访问变量:

1
2
3
4
5
function fun() {
console.log(a) //undefined
var a = 1
}
fun()

我们可以在变量被声明之前给变量赋值或者访问该变量,当我们给变量赋值时,如果在当前作用域的赋值操作后面声明了该变量,赋值操作为正常进行。如果在当前作用域未声明改变量,在当前作用域的父级或祖级作用域也未声明该变量,那么JavaScript会帮我们在全局作用域使用var创建一个变量然后进行赋值。如果在当前作用域的父级或祖级作用域中声明了该变量,我们知道引擎会将变量赋值给父级或祖级作用域中的变量。

使用let或const声明变量

es6新增了let和const声明符用来声明变量和常量,在本文中我只会讨论关于暂时性死区的问题。在es规范中,使用let和const声明变量是没有变量提升的,所以会出现以下情况:

在变量被声明之前访问变量或给变量赋值:

1
2
3
4
5
6
function fun() {
console.log(a) // ReferenceError: a is not defined
a = 2 //ReferenceError: a is not defined
let a = 1
}
fun()

或者:

1
2
3
4
5
6
function fun() {
console.log(a) // ReferenceError: a is not defined
a = 2 //ReferenceError: a is not defined
const a
}
fun()

如果在变量被声明之后访问该变量,一切正常:

1
2
3
4
5
function fun() {
const a
console.log(a) // undefined
}
fun()

所谓暂时性死区就是指使用let或const在当前作用域声明变量时,如果在变量被声明之前访问该变量,会造成引用错误,因为此时变量没有被声明。本质是let和const没有变量提升,变量声明不会被提升到当前作用域的最前面,所以在变量声明之前访问不到。