【前端每天一题】第 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 ✔
相关推荐
前端一课1 小时前
【前端每天一题】🔥第四题 原型与原型链 - 前端面试必考题
前端·面试
初见0011 小时前
告别无限循环:深入理解并征服 React Hooks 的依赖数组
前端
一颗不甘坠落的流星1 小时前
【HTML】iframe 标签 allow 权限汇总(例如添加复制粘贴权限)
前端·javascript·html
亦草1 小时前
浅谈现代前端体系:组件化、模块化、类型系统与工程化
前端
IT_陈寒1 小时前
JavaScript开发者必知的7个ES2023新特性,让你的代码效率提升50%
前端·人工智能·后端
前端一课1 小时前
【前端每天一题】🔥 第 1 题:什么是 闭包(Closure)?它有什么作用?
前端·面试
j***63081 小时前
SpringbootActuator未授权访问漏洞
android·前端·后端
ze_juejin1 小时前
JavaScript事件循环总结
前端
forestsea2 小时前
现代 JavaScript 加密技术详解:Web Crypto API 与常见算法实践
前端·javascript·算法