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