← 返回目录

8. 作用域与作用域链

作用域就是变量的「地盘」:一个名字在哪个范围里才作数、出了门就不认得。想象公司隔间:你在自己工位(局部)能放东西,公共大厅(全局)谁都能放,会议室(块级)里 let 放的东西出门就看不见。搞懂它,你才知道「为什么这个变量找不到」。

8.1 互动演示(三种作用域 + 作用域链就近查找)

点按钮看:全局/局部/块级的差别,以及「就近查找、不会向内」的作用域链。

8.2 知识点逐条讲解(配合代码)

① 三种地盘

地盘在哪特点
全局(公共大厅)整个 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();

	

如果你在里面又起了个同名变量,外面那个就被「挡住」了。因为就近原则,里面用自己的,看不到外面的。想让里面用外面的,里面就别再定义同名的。

⑥ X.3 实战:用在哪 / 常见坑 / 怎么解决

① 用在哪:读别人代码找变量为什么找不到、防止多个函数互相污染同名变量。

② 常见坑:let 出了 {} 还想用,报 ReferenceError;函数内外同名变量搞不清用了哪个。

③ 怎么解决:养成用 let/const 的习惯;变量找不到就沿作用域链从内往外查同名。

一句话记住:全局哪都能用、局部出函数就没、块级只认 let/const 不认 var;作用域链就近找、只往外不往里;同名里面挡住外面