【前端每天一题】第 2 题:var、let、const 的区别?(绝对高频)

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 ✔
相关推荐
掘金安东尼几秒前
用 CSS 打造完美的饼图
前端·css
掘金安东尼8 小时前
纯 CSS 实现弹性文字效果
前端·css
牛奶8 小时前
Vue 基础理论 & API 使用
前端·vue.js·面试
牛奶8 小时前
Vue 底层原理 & 新特性
前端·vue.js·面试
anOnion9 小时前
构建无障碍组件之Radio group pattern
前端·html·交互设计
pe7er9 小时前
状态提升:前端开发中的状态管理的设计思想
前端·vue.js·react.js
NAGNIP9 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
SoaringHeart10 小时前
Flutter调试组件:打印任意组件尺寸位置信息 NRenderBox
前端·flutter
晚风予星10 小时前
Ant Design Token Lens 迎来了全面升级!支持在 .tsx 或 .ts 文件中直接使用 Design Token
前端·react.js·visual studio code
sunny_10 小时前
⚡️ vite-plugin-oxc:从 Babel 到 Oxc,我为 Vite 写了一个高性能编译插件
前端·webpack·架构