iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0
自我挑戰組

重新開始 JavaScript系列 第 5

[Day5] 範圍鍊

什麼是範圍鍊(Scope Chain)

範圍鍊是指當函式本身沒有所需的變數時,會向外層尋找該變數,而範圍鍊只取決於函式的作用域,與執行環境無關。

範圍鍊的範例

下面 4 個例子,皆以程式的運作過程來撰寫,當作複習昨天的執行環境與執行堆疊,但需要注意的是範圍鍊只取決於函式的作用域,與執行環境無關,又因 JavaScript 是靜態作用域的關係,在寫下程式碼時就已經決定作用域,所以當函式本身沒有需要的變數時,會向外層尋找該變數

範例1:

  • 進入全域執行環境,命名 變數 name 賦予值 Carol,呼叫 函式 fn2
  • 進入 函式 fn2 執行環境,命名 變數 name 賦予值 Carol,呼叫 函式 fn1
  • 進入 函式 fn1 執行環境,在 函式 fn1 需要 變數 name,在內層找不到,就會向外層 全域環境 中尋找 變數 name
  • 離開 函式 fn1 執行環境
  • 離開 函式 fn2 執行環境
  • 離開 全域執行環境
var name = 'Carol';
function fn1() {
    console.log(name);
    // 範圍鍊指向全域環境,故顯示 Carol
}

function fn2() {
    var name = 'Marry';
    fn1();
}

fn2();

範例2:

  • 進入全域執行環境,命名 變數 name 賦予值 Carol,呼叫 函式 fn1
  • 進入 函式 fn1 執行環境,在函式內命名 變數 name 賦予值 Mary,呼叫 函式 fn2
  • 進入 函式 fn2 執行環境,需要 變數 name,在函式內找到 變數 name,故顯示 Casper
  • 離開 函式 fn2 執行環境
  • 離開 函式 fn1 執行環境
  • 離開 全域執行環境
var name = 'Carol';

function fn1() {
    var name = 'Marry';
    function fn2() {
        var name = 'Casper';
        console.log(name); // Casper
    }
    fn2();
}

fn1();

範例3:

  • 進入全域執行環境,命名 變數 name 賦予值 Carol,呼叫 函式 fn1
  • 進入 函式 fn1 執行環境,在函式內命名 變數 name 賦予值 Mary,呼叫 函式 fn2
  • 進入 函式 fn2 執行環境,需要 變數 name,因在函式內找不到,向外層 函式 fn1 尋找,故顯示 Marry
  • 離開 函式 fn2 執行環境
  • 離開 函式 fn1 執行環境
  • 離開 全域執行環境
var name = 'Carol';
function fn1() {
    var name = 'Marry';
    function fn2() {
        console.log(name); // Marry
    }
    fn2();
}

fn1();

範例4:

  • 進入 全域執行環境,命名 變數 name 賦予值 Carol,呼叫 函式 fn1
  • 進入 函式 fn1 執行環境,在函式內命名 變數 name 賦予值 Mary,呼叫 函式 fn2
  • 進入 函式 fn2 執行環境,需要 變數 name,因在函式內找不到,向外層 函式 fn1 尋找,也找不到,再向外層 全域執行環境 中尋找,故顯示 Carol
  • 離開 函式 fn2 執行環境
  • 離開 函式 fn1 執行環境
  • 離開 全域執行環境
var name = 'Carol';
function fn1() {
    function fn2() {
        console.log(name); // Carol
    }
    fn2();
}

fn1();

參考文獻

六角學院 - JavaScript 核心篇

圖片待補


上一篇
[Day4] 執行環境與執行堆疊
下一篇
[Day6] 'undefined' vs 'not defined'
系列文
重新開始 JavaScript32

尚未有邦友留言

立即登入留言