块级作用域 vs 函数作用域
在 JavaScript 中,作用域决定了变量的可访问范围。理解块级作用域和函数作用域的区别对于编写可靠的代码非常重要。
函数作用域 (Function Scope)
使用 var 声明的变量具有函数作用域:
function example() {
if (true) {
var functionScoped = "我在函数内任何地方都可用";
}
console.log(functionScoped); // 正常工作
}
example();
console.log(functionScoped); // ReferenceError
特点:
- 变量在整个函数内部都可访问
- 不受代码块(如 if、for 等)限制
- 存在变量提升(hoisting)现象
块级作用域 (Block Scope)
使用 let 和 const 声明的变量具有块级作用域:
function example() {
if (true) {
let blockScoped = "我只在这个代码块内可用";
const alsoBlockScoped = "我也是";
}
console.log(blockScoped); // ReferenceError
console.log(alsoBlockScoped); // ReferenceError
}
特点:
- 变量只在声明它的代码块(
{}内部)内可访问 - 适用于 if、for、while 等代码块
- 不存在变量提升(有暂时性死区)
关键区别对比
| 特性 | 函数作用域 (var) | 块级作用域 (let/const) |
|---|---|---|
| 作用范围 | 整个函数内 | 仅声明所在的代码块内 |
| 是否提升 | 是 | 否(有暂时性死区) |
| 循环中的表现 | 最后一次赋值影响全部 | 每次迭代都有独立绑定 |
| 重复声明 | 允许 | 不允许 |
| 全局声明时 | 成为全局对象属性 | 不在全局对象上 |
实际应用示例
1. 循环中的差异
// 使用 var
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 输出 3, 3, 3
}
// 使用 let
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 输出 0, 1, 2
}
2. if 语句中的差异
function checkCondition(condition) {
if (condition) {
var functionVar = "function scope";
let blockLet = "block scope";
}
console.log(functionVar); // "function scope"(可访问)
console.log(blockLet); // ReferenceError(不可访问)
}
最佳实践
- 优先使用
const:默认使用const声明变量,除非需要重新赋值 - 其次使用
let:需要重新赋值的变量使用let - 避免使用
var:除非有特殊需求或维护旧代码 - 注意暂时性死区:在声明前访问
let/const变量会报错

被折叠的 条评论
为什么被折叠?



