作用域(scope)是一个变量、函数或对象的可访问范围。以下是JavaScript中作用域的几种类型和相关概念:
1. 全局作用域(Global Scope)
任何在全局作用域中声明的变量或函数都可以在代码的任何地方访问。全局变量在浏览器环境中会成为window
对象的属性。
javascript
var global = "global variable";
function globalFunction() {
console.log(global); // global varable
}
2. 函数作用域(Function Scope)
在函数内部声明的变量只能在该函数内部访问。使用var
声明的变量具有函数作用域。
javascript
function functionScope() {
var localVar = "local variable";
console.log(localVar);
}
console.log(localVar); // Error: localVar is not defined
3. 块级作用域(Block Scope)
块级作用域由花括号{}
包围的代码块定义。在let
和const
引入之前,JavaScript没有块级作用域。let
和const
允许我们在块级作用域内声明变量。
javascript
{
let blockVar = "I'm a block-scoped variable";
console.log(blockVar);
}
console.log(blockVar); // Error: blockVar is not defined
4. 词法作用域(Lexical Scope)
JavaScript采用词法作用域,也称为静态作用域。这意味着函数的作用域在定义时就已经确定,而不是在调用时确定。
javascript
function outerFunction() {
var outerVar = "I'm outside!";
function innerFunction() {
console.log(outerVar); // 可以访问outerFunction中的变量
}
innerFunction();
}
outerFunction();
5. 闭包(Closure)
闭包是指有权访问另一个函数作用域中的变量的函数。即使外部函数已经执行完毕,内部函数仍然可以访问外部函数的变量。
javascript
function outerFunction() {
var outerVar = "I'm outside!";
return function innerFunction() {
console.log(outerVar);
};
}
var closureFunction = outerFunction();
closureFunction(); // "I'm outside!"
6. 模块作用域(Module Scope)
在ES6中,引入了模块,模块中的变量默认具有模块作用域。一个模块的变量在其他模块中是不可见的,除非明确导出并导入。
javascript
// module1.js
export const moduleVar = "I'm a module-scoped variable";
// module2.js
import { moduleVar } from './module1.js';
console.log(moduleVar);
作用域链(Scope Chain)
作用域链是指在当前作用域中无法找到某个变量时,JavaScript会沿着作用域链向上查找,直到找到该变量或到达全局作用域。
javascript
var globalVar = "Global";
function outerFunction() {
var outerVar = "Outer";
function innerFunction() {
var innerVar = "Inner";
console.log(innerVar); // Inner
console.log(outerVar); // Outer
console.log(globalVar); // Global
}
innerFunction();
}
outerFunction();