Var vs Let:大混淆解析!
发布: (2026年2月8日 GMT+8 06:43)
3 分钟阅读
原文: Dev.to
Source: Dev.to

这是对 “Let” 与 “Var” 概念的清晰阐述。
Let
你可能听说过 let 是块级作用域的。下面看看它在循环、函数和闭包中的具体表现。
循环示例(每次迭代新变量)
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Output: 0, 1, 2
函数示例(块级遮蔽)
function test() {
let x = 10; // 外层 x
if (true) {
let x = 20; // 新的 x(遮蔽外层 x)
console.log(x); // 20
}
console.log(x); // 10(外层 x 未改变)
}
let变量 在其块结束后不能被外部作用域访问。
闭包示例(每个块相互独立)
function createClosures() {
const closures = [];
for (let i = 0; i < 3; i++) {
closures[i] = () => console.log(i); // 每个 i 拥有自己的闭包
}
closures[0](); // 0
closures[1](); // 1
closures[2](); // 2
}
闭包 是记住外层函数作用域变量的函数。
Var
var 最让人困惑的地方在于它在循环中的行为。
循环示例
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Output: 3, 3, 3
逐步说明:
- 第一次迭代:
var i = 0→ 创建了一个变量。 - 第二次迭代:
i = 1→ 同一个变量,值被修改。 - 第三次迭代:
i = 2→ 同一个变量,值被修改。 - 循环结束:
i = 3→ 最终值。
所有三个 setTimeout 在循环结束后才执行,所以 console.log(i) 打印 3。
函数作用域示例
function test() {
if (true) {
var x = 10; // 函数作用域,而非块级作用域
}
console.log(x); // 10 – 在函数内部任何位置都可访问
}
Var vs Let – 真正的区别
| 场景 | var | let |
|---|---|---|
循环 + setTimeout | 3, 3, 3 | 0, 1, 2 |
在 { if } 块内部 | 块外仍可访问 | 抛出 ReferenceError |
| 同名变量在不同块中出现 | 同一个变量 | 每次出现都是新变量 |
| 作用域 | 函数/全局 | 仅块级 |
简要结论
var= 一个变量,值会被改变。let= 每个块都会生成一个新变量。