Sean's Blog

An image showing avatar

Hi, I'm Sean

這裡記錄我學習網站開發的筆記
歡迎交流 (ゝ∀・)b

LinkedInGitHub

Understand JavaScript #2 語法作用域 (Lexical Scope)

JavaScript 是屬於語法作用域(靜態作用域),而靜態作用域與動態作用域這兩者有何不同呢。

詞彙環境 (Lexical Environment)

詞彙環境指程式碼被「寫在哪裡」,程式碼實際執行的位置。這個位置可以影響在執行階段時,它所對應的記憶體位置,也能影響它和其他周圍的變數與函式的互動。

因此,當 JavaScript 程式碼被撰寫,也就是定義了詞彙環境之後,同時也等同於定義了它的(語法)作用域。

語法作用域 (Lexical Scope) aka 靜態作用域

JavaScript 是語法作用域(又稱為靜態作用域),語法在解析時就已經確定作用域,且不會改變。

當作用域內沒有需要的變數時,JavaScript 就會向外查找,如果向外查找還是找不到,就會回傳 變數 is not defined 的錯誤。

下方範例中,因為 JavaScript 的作用域是在函式裡面,因此函式內會讀到 sean 這個變數,但是外層是讀不到的。

1function callName() {
2  var sean = 'Sean';
3  console.log(sean);
4}
5
6callName(); // Sean
7console.log(sean); // Sean is not defined
8

動態作用域

在函式調用時才會決定作用域。

以下範例說明靜態作用域與動態作用域,在使用時兩者之間的差異。

1var value = 1;
2
3function fn1() {
4  console.log(value); // 語法作用域:1
5  // 若是動態作用域,這裡則會得到 2
6}
7
8function fn2() {
9  var value = 2;
10  fn1();
11}
12
13fn2();
14

如果是語法作用域 (JavaScript),var value = 2; 的作用域只在 fn2 裡面,因此會得到 value 為 1 的結果。

但如果是動態作用域,則是在函式調用時才決定作用域,因此 fn1 會「向上一層的函式宣告的位置」來查找變數的值,因而取到 value 為 2 的值。

回顧

看完這篇文章,我們到底有什麼收穫呢?藉由本文可以理解到…

  • 語法作用域(靜態作用域)與動態作用域的差異
  • JavaScript 是屬於語法作用域

References