跳到主要内容
← 返回文章列表
面试题-基础2026/08/09约 3 分钟读完

面试题:var 变量提升与 let 暂时性死区

本题考察 JavaScript 的变量提升、词法作用域和暂时性死区,重点区分 var 与 let 在执行阶段的不同表现。

面试题:var 变量提升与 let 暂时性死区
文章目录 8

题目简述

本题考察 JavaScript 的变量提升、词法作用域和暂时性死区,重点是区分 var 与 let 在执行阶段的不同表现。

面试题

下面代码的执行结果是什么?请解释原因。

console.log(value);

var value = 'global';

function test() {
  console.log(value);

  let value = 'local';

  console.log(value);
}

test();

请回答:

  1. 第一个 console.log(value) 输出什么?

  2. test() 内第一个 console.log(value) 输出什么,还是抛出异常?

  3. 为什么函数内不会读取外层的 'global'?

  4. 什么是暂时性死区(TDZ)?

解答

这次对“内部声明会遮蔽外部变量”有一定认识,但两个输出结果都不正确。评分:3.5/10。

正确点:

  • 认识到函数内部的 let value 会影响变量查找。

  • 知道 let 与暂时性死区有关。

  • 知道需要从词法环境和变量声明角度解释。

正确执行结果

undefined
ReferenceError: Cannot access 'value' before initialization

函数中的第三个 console.log 不会执行,因为程序已经抛出异常。

1. 为什么不是 global

console.log(value);
var value = 'global';

var value 的声明会在代码执行前完成初始化,初始值为 undefined,但赋值仍然发生在原位置。

可以近似理解为:

var value;

console.log(value); // undefined

value = 'global';

所以第一个输出是:

undefined

2. 为什么不是 local

function test() {
  console.log(value);
  let value = 'local';
}

进入 test 的函数体作用域时,JavaScript 已经知道内部存在一个 value 绑定。因此它会遮蔽外层的全局 value。

但是,在执行到下面这行之前:

let value = 'local';

内部 value 还没有完成初始化,正处于暂时性死区。因此访问它会抛出:

ReferenceError: Cannot access 'value' before initialization

不能把代码理解为:

let value;
console.log(value);
value = 'local';

因为 let 在声明执行前不是 undefined,而是不可访问。

3. 为什么不继续查找全局变量

变量查找并不是“当前作用域的变量不能访问,就继续向外查找”。

实际情况是:

test 词法环境
└─ 找到内部 value,但它还未初始化
   → 立即抛出 ReferenceError
   → 不再向全局环境查找

只要当前作用域存在同名绑定,就会遮蔽外层绑定,即使当前绑定还处于 TDZ。

4. TDZ 的准确定义

暂时性死区是:

从进入包含 let、const 或 class 声明的作用域开始,到代码执行至该声明并完成初始化之前的区域。

这里的 TDZ 是:

function test() {
  // value 的 TDZ 开始

  console.log(value); // ReferenceError

  let value = 'local'; // 初始化完成,TDZ 结束

  console.log(value); // 如果前面没有报错,这里输出 local
}

标准回答可以概括为:

第一个 console.log 输出 undefined,因为 var 声明阶段就被初始化为 undefined,但赋值仍在原位置执行。进入 test 后,内部的 let value 会遮蔽全局变量,但执行声明语句前它处于 TDZ,因此函数内第一次访问会抛出 ReferenceError,不会读取全局变量,后续代码也不会继续执行。

评论

0 条

评论会在审核后展示,邮箱不会公开。

正在确认登录状态

5000 / 5000