作用域就是变量的「地盘」:一个名字在哪个范围里才作数、出了门就不认得。想象公司隔间:你在自己工位(局部)能放东西,公共大厅(全局)谁都能放,会议室(块级)里 let 放的东西出门就看不见。搞懂它,你才知道「为什么这个变量找不到」。
| 地盘 | 在哪 | 特点 |
|---|---|---|
| 全局(公共大厅) | 整个 script | 哪都能用,页面关才销毁 |
| 函数局部(自己工位) | function 里面 | 只有函数内能用,执行完就收走 |
| 块级(会议室) | if/for 后的 {} | 只对 let/const 生效,var 不认 |
// var 不认 {}:括号外面照样能用
if (true) {
var num = 123; // var 写在哪都算全局
}
console.log(num); // 123,外面照样取得到
// let 认 {}:出了括号就找不到
if (true) {
let n = 10; // let 只在这对括号里有效
}
console.log(n); // 报错:n is not defined(出门就没了)
函数套函数时,里面那层能用外面那层的变量。找东西的规矩:先翻自己抽屉,没有就翻上一层,一直翻到公共大厅;绝不会往更里面翻。
let num = 456; // 全局放了个 num
function f1() {
let num = 123; // f1 里又放了个同名 num
function f2() {
console.log(num); // f2 先找自己 → 再找 f1 → 拿到 123
}
f2(); // 不去全局拿 456
}
f1();
如果你在里面又起了个同名变量,外面那个就被「挡住」了。因为就近原则,里面用自己的,看不到外面的。想让里面用外面的,里面就别再定义同名的。
① 用在哪:读别人代码找变量为什么找不到、防止多个函数互相污染同名变量。
② 常见坑:let 出了 {} 还想用,报 ReferenceError;函数内外同名变量搞不清用了哪个。
③ 怎么解决:养成用 let/const 的习惯;变量找不到就沿作用域链从内往外查同名。