作用域是指程式中變數的可訪問範圍,也就是變數在哪裡可以被存取。
JavaScript 有幾種作用域類型:
變數在程式最外層定義,任何地方都可以存取。
var globalVar1 = "我是全域的1";
let globalVar2 = "我是全域的2";
const globalVar3 = "我是全域的3";
function sayHi() {
console.log(globalVar1); // 輸出:我是全域的1
console.log(globalVar2); // 輸出:我是全域的2
console.log(globalVar3); // 輸出:我是全域的3
}
sayHi();
在函數內宣告的變數,只能在該函數內存取,外層無法看到。
function test() {
var localVar = "我是區域的";
console.log(localVar); // 輸出:我是區域的
}
test();
console.log(localVar); // 報錯:ReferenceError
使用 let
或 const
宣告的變數,限制在 {}
塊內(比如 if
或 for
)。
var
沒有塊級作用域,會穿透{}
塊。
if (true) {
let blockVar = "我在塊裡";
var notBlockVar = "我跑出去";
console.log(blockVar); // 輸出:我在塊裡
}
console.log(blockVar); // 報錯:ReferenceError
console.log(notBlockVar); // 輸出:我跑出去
在 ES6 模組(.js 檔案使用 import/export)中,變數預設限制在模組內,除非明確匯出(export)。
模組作用域類似於一個獨立的作用域,外界無法直接存取模組內的變數。
// module.js
let moduleVar = "模組內變數";
export function sayHi() {
console.log(moduleVar); // 輸出:模組內變數
}
// main.js
import { sayHi } from './module.js';
sayHi(); // 輸出:模組內變數
console.log(moduleVar); // 報錯:ReferenceError
特性:
JavaScript 解析變數時的查找機制。當程式需要存取某個變數時,會從當前作用域開始,沿著外層作用域逐級查找,直到全域作用域。
var outer = "外層";
function innerFunc() {
console.log(outer); // 輸出:外層
}
innerFunc();
innerFunc 內找不到 outerVar,於是沿著作用域鏈往外找,找到全域作用域的 outerVar。