var、let、const 的区别(前端面试高频题)
这是所有前端面试必问 TOP3 的题,你必须答得全面、精准、有条理。
0. 面试"一句话标准答案"
var 是函数作用域,有变量提升,可重复声明。
let 和 const 是块级作用域,存在暂时性死区,不可重复声明;const 绑定不可变但对象内容可变。
如果一分钟要答完,这是最优答案。
1. 作用域(第一重点)
var:函数作用域(Function Scope)
javascript
function f() {
if (true) {
var x = 1;
}
console.log(x); // 1
}
let / const:块级作用域(Block Scope)
javascript
if (true) {
let a = 1;
const b = 2;
}
console.log(a); // ReferenceError
关键点:块级作用域能有效避免变量污染 → 面试官喜欢你强调这一点。
2. 是否会被提升(Hoisting)
三者都会提升!但初始化行为不同。
| 声明方式 | 提升? | 初始值 | 是否进入暂时性死区 |
|---|---|---|---|
| var | ✔ | undefined | ❌ |
| let | ✔ | 未初始化 | ✔(TDZ) |
| const | ✔ | 未初始化 | ✔(TDZ) |
经典示例
javascript
console.log(a); // undefined
var a = 1;
console.log(b); // ReferenceError(TDZ)
let b = 2;
记住:TDZ(暂时性死区)是面试必问点。
3. 是否可重复声明
javascript
var x = 1;
var x = 2; // ✔️
let y = 1;
let y = 2; // ❌
const z = 1;
const z = 2; // ❌
为什么禁止重复声明?
因为块级作用域下重复声明容易导致不可预期的覆盖。
4. 是否可修改
| 声明方式 | 变量可变? |
|---|---|
| var | ✔ |
| let | ✔ |
| const | ❌(绑定不可变) |
注意
const 的"不可变"指的是变量绑定不可变,不是内容不可变:
javascript
const obj = { a: 1 };
obj.a = 2; // ✔ okay
obj = {}; // ❌ TypeError
5. 全局对象挂载(面试常见追问)
在浏览器中:
var → 会挂在 window 上(不推荐)
javascript
var a = 1;
console.log(window.a); // 1
let / const → 不会挂在 window 上(安全)
javascript
let b = 2;
console.log(window.b); // undefined
let/const 更安全,不污染全局对象,是 ES6 推出的原因之一。
6. for 循环中的行为区别(高频陷阱)
6.1 var 的经典面试陷阱
javascript
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i));
}
输出:
3
3
3
原因:三个函数共享同一个 i。
6.2 let 自动创建块级作用域
javascript
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i));
}
输出:
0
1
2
原因:每轮循环都有一个独立的 i。
7. const 的本质(很多候选人答错)
- const 仅仅保证变量绑定不可变,不保证值不可变
- 如果值是对象,则对象属性仍可更改
- 如果值是基本类型,则彻底不可变(因为绑定不允许重新赋值)
回答时强调"绑定不可变"会加分。
8. 执行上下文对它们的影响(高级理解)
- var 进入 Variable Environment(VE)
- let、const 进入 Lexical Environment(LE)
LE 在创建时会标记未初始化,从而形成 TDZ(暂时性死区)
这是为什么"提升但不能访问"。
9. 面试标准作答模板(满分答案)
var 是函数作用域,有变量提升,并且初始化为 undefined,可重复声明,会挂在 window 上。
let 和 const 是 ES6 引入的块级作用域声明方式,存在暂时性死区,不可重复声明,也不会挂在全局对象上。
区别是 let 可重新赋值,const 绑定不可变但对象内容可变。
建议默认使用 const,仅在需要修改变量时使用 let。
这是最优雅的面试回答模板。
10. 常见追问
Q1:为什么要引入 let/const?
因为 var 有以下问题:
- 无法避免变量提升带来的怪异行为
- 函数作用域导致变量污染大
- 不支持块级作用域
- 会挂到 window 上导致全局污染
Q2:为什么 let/const 会有 TDZ?
为了消除变量提升带来的"使用未定义变量"的隐患,使 JS 行为更可预期。
Q3:应该如何选择?
- 默认用 const
- 需要改变值时用 let
- 永远不要用 var
这是现代前端的黄金准则。
11. 速记卡片
《var / let / const 速记卡片》
作用域
- var:函数作用域
- let/const:块级作用域 ✔
提升(Hoisting)
- var:提升并赋 undefined
- let/const:提升但不初始化 → TDZ ✔
可否重复声明
- var:✔
- let/const:✘
可否修改
- var:✔
- let:✔
- const:绑定不可变(对象内容可变)
全局属性
- var:会挂到 window
- let/const:不会 ✔
推荐用法
- 默认 const
- 需要修改时用 let
- 禁用 var ✔