跳至主要内容

Javascript 的作用域(Scope)

什麼是 Scope?

Scope 是定義變數的可見性或作用域的範圍,它確定了變數在哪裡可以被訪問或使用。在 JavaScript 中,作用域分為全域作用域(Global Scope)函式作用域(Function Scope),以及由 let 和 const 創建的區塊作用域(Block Scope)


Global Scope

在 JavaScript 中,所有在函式外部宣告的變數都屬於全域作用域。這意味著這些變數可以在程式碼的任何位置被訪問和使用。例如:

var message = "Hello, world!";

function showMessage() {
console.log(message);
}

showMessage(); // "Hello, world!"

這裡的 message 變數宣告在函式之外,因此它是一個全域變數,可以在任何地方使用。


Function Scope

在 JavaScript 中,每當定義一個函式時,都會創建一個新的函式作用域。在函式中宣告的變數只能在函式內部使用,不能在函式外部訪問。例如:

function showMessage() {
var message = "Hello, world!";
console.log(message);
}

showMessage(); // "Hello, world!"
console.log(message); // ReferenceError: message is not defined

在這裡, message 變數是在函式中宣告的,它只能在該函式內部使用,如果在函式之外嘗試訪問它,則會出現引用錯誤。


Block Scope

在 ES6 中,可以使用 let 和 const 關鍵字來宣告區塊作用域的變數。區塊是指花括號 中的任何程式碼區域,例如 if 語句或 for 循環。這意味著變數的可見範圍僅限於宣告該變數的區塊內。例如:

if (true) {
let x = 1;
const y = 2;
var z = 3;
console.log(x, y, z); // 1 2 3
}

console.log(x, y, z); // ReferenceError: x is not defined, ReferenceError: y is not defined, 3

在上述範例中,x 和 y 僅存在於 if 區塊內部,因此在區塊外部無法存取。而 z 則是使用 var 宣告的變數,其作用域為 Function Scope,因此可以在區塊外部存取。

提示

很多人常常搞混 var 的變數範圍,以為 var 可以在 外存取所以 var 是全域變數,但實際上 var 的作用範圍是 function scope,若在一個函數內使用 var 宣告變數,是沒辦法在其他函數使用的。


常見的使用錯誤

在未宣告變數時賦值

function myFunction() {
x = 1;
console.log(x);
}

myFunction(); // 1
console.log(x); // 1

在上述範例中,變數 x 並沒有使用 var letconst等方式宣告,因此它會自動被建立為全域變數。這會造成許多問題,因為全域變數會對整個應用程式產生影響,也可能會被其他函式意外修改到。

變數提升(Hoisting)

JavaScript 具有變數提升(Hoisting)的特性,即在一個作用域中宣告的變數,無論宣告的位置在哪裡,都會被提升至作用域頂部,且可以在宣告之前被使用,但若在被使用前未被賦值,其職將為 undefined

console.log(a); // undefined
var a = 1;

Reference