作用域指的是「變數或函式在程式中可以被存取的範圍」。JavaScript 的作用域主要有三種:全域作用域、函式作用域、區塊作用域。
變數或函式的宣告可以參考這篇文章:【JavaScript 入門:一表看懂 var / let / const 三種宣告方式差異】
全域作用域 Global Scope
宣告在程式最外層(函式外)的變數,屬於全域作用域,在整個程式內都能被存取。
var a = 5;
let b = 6;
const c = 7;
function test(){
console.log(`${a},${b},${c}`);
}
test(); // 5, 6, 7
因為 a, b, c 三者宣告在最外層,函式內部可以存取。
全域物件
事實上,用 var 宣告的全域變數會成為全域物件的屬性,而 let 與 const 宣告的全域變數則不會成為全域物件的屬性喔!
全域物件會依照 Javascript 的執行環境有所區別,以網頁來說的全域物件就是 window,可以用 window.variable 來設定與存取全域變數。
var a = 10;
let b = 15;
console.log(window.a); // 10
console.log(window.b); // undefined
函式作用域 Function Scope
在函式內使用 var 宣告變數,變數的作用域會被限制在函式內。
function test(){
var a = 5;
console.log(a);
}
test(); // 5, 可順利印出
console.log(a); //錯誤, ReferenceError: a is not defined
變數 a 使用 var 宣告在 function 內部,因此函式外無法存取。
區塊作用域 Block Scope
使用 let 與 const 宣告,變數/常數只會在{}內有效。
if(true){
let a = 1;
const b = 2;
}
console.log(a); //錯誤, ReferenceError: a is not defined
console.log(b); //錯誤, ReferenceError: a is not defined
let 與 const 都是區塊作用域,脫離 {} 就無法存取了。
作用域鏈 Scope Chain
在使用變數時,Javascript 會在當前的作用域尋找被使用的變數,如果沒找到就往外面一層一層找,這樣的層層向外的關係就是作用域鏈。但要留意的是,作用域鏈是「由內向外」的關係,只有內層看得到外面,外層無法向裡面看。先知道了作用域的概念,後續可以幫我們更好理解閉包的運作原理。












