JavaScript中嵌套作用域的遮蔽效应指内层声明同名变量时覆盖外层变量,仅限词法作用域内生效;var在函数级、let/const在块级触发遮蔽;被遮蔽变量仍存在但不可见;循环中var易致异步回调输出异常,let可避免。

JavaScript 中嵌套作用域的遮蔽效应,是指内层作用域声明了与外层作用域同名的变量时,内层变量会“盖住”外层变量——在内层作用域中,直接访问该变量名时,始终读取的是内层定义的那个,而不会去查外层。
遮蔽只发生在声明位置决定的作用域内
JS 使用词法作用域(静态作用域),变量是否被遮蔽,取决于代码写在哪里,而不是运行时怎么调用。只要内层有 var / let / const 声明了同名变量,就会触发遮蔽。
- var:函数作用域内声明会遮蔽同名的外层函数或全局变量
-
let / const:块级作用域(如
{}、if、for)内声明会遮蔽同名的外层变量,包括同函数内的 var 变量
常见遮蔽场景举例
比如这段代码:
let x = 10;
function foo() {
let x = 20; // 遮蔽外层 let x
if (true) {
const x = 30; // 遮蔽外层 let x(函数内那个)
console.log(x); // 30
}
console.log(x); // 20
}
foo();
console.log(x); // 10
三个 x 各自独立,互不干扰,访问哪个取决于当前执行位置所处的词法作用域层级。
遮蔽不影响外层变量本身
被遮蔽的变量没有消失,也没有被修改,它依然存在且值不变。只是在当前作用域里“不可见”了。
- 想访问被遮蔽的外层变量?JS 没有类似 Java 的
OuterClass.this.x语法 - 但你可以提前重命名变量(如
outerX)、或用不同作用域结构规避(例如不用同名) - 特别注意:
var在函数内重复声明不会报错,但仍是遮蔽;let/const在同一块内重复声明会直接报错
容易忽略的遮蔽陷阱
最典型的是循环 + 异步回调中的 var 遮蔽问题:
for (var i = 0; i console.log(i), 100); }
输出是 3 3 3,不是 0 1 2。因为 var i 是函数作用域,整个循环共用一个 i,最后值为 3;每次回调访问的都是这同一个被遮蔽(更准确说是共享)的变量。
改用 let i 就能按预期输出 —— 因为每次迭代都会创建一个新的块级绑定,let 在每次循环中都生成一个独立的 i,不存在跨轮次遮蔽,而是各自封闭。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











