临时死区(Temporal Dead Zone) 和 变量提升(Hoisting) 是 JavaScript 中的两个基本术语。今天就让我们来深入了解一下他们。
什么是临时死区?
TDZ 指的是从块的起始位置开始,一直到变量正式声明的这一段代码区域。在这个区域内,变量虽然已经存在于作用域之中,但还不可以被访问。一旦尝试访问,就会抛出ReferenceError异常。
下面是一个实例:
{
// 'name'的TDZ从这里开始(块的开始位置)
// 'name'的TDZ还在
// 'name'的TDZ还在
// 'name'的TDZ还在
console.log(name);// 错误:Cannot access 'name' before initialization
let name='曾同学'//TDZ结束
//TDZ不存在了
//TDZ不存在了
}
当我们运行这段代码时,会出现ReferenceError: Cannot access 'name' before initialization这样的报错,这是因为name这个变量还没有声明,但是我们又进行了访问。换句话说,我们在临时死区内调用。
接下来我们来一个正常声明的实例:
{
// 'name'的TDZ从这里开始(块的开始位置)
// 'name'的TDZ还在
// 'name'的TDZ还在
// 'name'的TDZ还在
let name='曾同学'//TDZ结束(name变量已经被正式声明了)
console.log(name);//TDZ结束了,我们没有在TDZ中调用,所以正常输出
//TDZ不存在了
//TDZ不存在了
}
让我们来考虑下面这个实例:
{
// TDZ开始
// TDZ 还在
//TDZ 还在
let name;// TDZ结束
console.log(name);// 返回undefined 因为name没有分配值
name = '曾同学';
console.log(name);// 返回曾同学
}
因此,我们在声明变量的时候要进行赋值
Var 的 TDZ 与 let 和 const 变量有何不同?
var和 let``const变量的临时死区之间的主要区别在于它们的 TDZ 何时结束。
{
console.log(name);
var name = '曾同学';
}
运行完上面的代码后,会返回undefined
当计算机提升一个var变量时,它会自动使用undefined。
相比之下,JavaScript 在提升let``const变量时不会用任何值初始化变量。变量仍然是死的且不可访问的。
因此,当 JavaScript 使用其声明期间指定的值完全初始化变量时,let``const变量的 TDZ 将结束。
但是,var变量的 TDZ 在提升后立即结束,而不是在变量使用其声明期间指定的值完全初始化时结束。