JavaScript 主要有 4 种作用域:
1. 全局作用域(Global Scope)
在全局声明的变量,可以在整个全局环境中访问。
ini
var a = 10;
let b = 20;
function foo() {
console.log(a, b); // 10 20
}
注意:浏览器普通脚本中,顶层 var 通常会成为 window 的属性,而顶层 let、const 不会。
2. 函数作用域(Function Scope)
函数内部声明的变量,通常只能在函数内部访问。
ini
function foo() {
var a = 10;
let b = 20;
}
console.log(a); // ReferenceError
var、let、const 都具有函数作用域。
3. 块级作用域(Block Scope)
ES6 引入 let、const 后,可以在 {} 代码块中形成独立作用域。
ini
if (true) {
var a = 10;
let b = 20;
const c = 30;
}
console.log(a); // 10
console.log(b); // ReferenceError
关键区别:var 不受普通块级作用域限制,而 let、const 受限制。
4. 模块作用域(Module Scope)
ES Module 中,顶层声明的变量默认只能在当前模块中访问。
ini
// user.js
const name = "Tom";
export const age = 18;
其他模块只能访问显式导出的内容:
javascript
import { age } from "./user.js";
面试需要掌握的两个相关概念
① 词法作用域(Lexical Scope)
JavaScript 采用词法作用域,也叫静态作用域。
函数能访问哪些外部变量,由函数定义的位置决定,而不是调用的位置。
scss
let a = 10;
function foo() {
console.log(a);
}
function bar() {
let a = 20;
foo();
}
bar(); // 10
② 作用域链(Scope Chain)
访问变量时,JS 会先在当前作用域查找,如果找不到,就沿外层词法作用域逐级查找。
markdown
当前作用域
↓
外层函数作用域
↓
全局作用域
直到找到变量,或者最终抛出 ReferenceError。