iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
自我挑戰組

重新開始 JavaScript系列 第 3

[Day3] 作用域

作用域是原始碼中定義變數的區域,他規範了目前程式碼應該要去哪裡查找變數,而作用域又可分為 靜態作用域動態作用域,首先先來了解兩者的差別。

靜態作用域

定義

靜態作用域又稱作語法作用域(Lexical scoping),他在函數定義時就已經決定作用域,而且不會再改變,JavaScript 屬於此類。

範例

以下為靜態作用域範例,運作步驟如下:

  1. 先在全域命名一個 變數 num 賦予值 1。
  2. 呼叫 函式 fn2,在函式內命名一個 變數 num 賦予值 2,因靜態作用域的關係,函式 fn2 中的 變數 num,作用域只在 函式 fn2 中,接著呼叫 函式 fn1
  3. 函式 fn1 內因沒有 變數 num,又因靜態作用域的關係,所以會向外層(全域)查找,故 console.log(num); 顯示為 1
// 靜態作用域範例

var num = 1;

function fn1() {
    console.log(num); // 1
    // 因靜態作用域,又因 fn1 沒有變數 num,所以會向外(全域)查找
}

function fn2() {
    var num = 2;
    //變數 num 作用域只在函式 fn2 中
    fn1();
}

fn2();

動態作用域

定義

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

範例

以下為動態作用域範例,運作步驟如下:

  1. 先在全域命名一個 變數 num 賦予值 1。
  2. 呼叫 函式 fn2,在函式內命名一個 變數 num 賦予值 2,接著呼叫 函式 fn1
  3. 函式 fn1 內因沒有 變數 num,又因動態作用域的關係 - 函式調用時才會決定作用域,所以會向上一層 函式 fn2 查找 變數 num,故 console.log(num); 顯示為 2
// 動態作用域範例

var num = 1;

function fn1() {
    console.log(num); // 2
    // 因動態作用域,在函式調用時才會決定作用域,所以會向上一層 fn2 宣告的位置找變數的值
}

function fn2() {
    var num = 2;
    fn1();
}

fn2();

錯誤訊息

若所有作用域都找不到變數時,則會出現 ReferenceError: 變數 is not defined 的錯誤訊息,範例如下。

參考文獻

六角學院 - JavaScript 核心篇


上一篇
[Day2] 何謂 LHS、RHS 錯誤?
下一篇
[Day4] 執行環境與執行堆疊
系列文
重新開始 JavaScript32

尚未有邦友留言

立即登入留言