JavaScript 中的临时死区 (TDZ) – 通过示例解释

203 阅读2分钟

临时死区(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 变量有何不同?

varlet``const变量的临时死区之间的主要区别在于它们的 TDZ 何时结束。

{
    console.log(name);
    var name = '曾同学';
}

运行完上面的代码后,会返回undefined

当计算机提升一个var变量时,它会自动使用undefined

相比之下,JavaScript 在提升let``const变量时不会用任何值初始化变量。变量仍然是死的且不可访问的。

因此,当 JavaScript 使用其声明期间指定的值完全初始化变量时,let``const变量的 TDZ 将结束。

但是,var变量的 TDZ 在提升后立即结束,而不是在变量使用其声明期间指定的值完全初始化时结束。