iT邦幫忙

0

ES6 學習筆記_03(作用鏈)

作用鏈

在JavaScript中,函數可以製造一個作用域(函數作用域),如果函數中還有函數那麼這個作用域中又會建立一個作用域,將所有的作用域列出來可以獲得一個結構,一個函數內指向函數外的鏈式結構。

而作用鏈相當於一個物件的鏈表,如果要找一個變數X,會從這個作用鏈當前有權限訪問的最底層物件開是找,如果這個最底層的物件有X這個變數就直接使用,若沒有則會向上層尋找有沒有這個變數一直找到作用鏈的頂部(全域),如果都沒有則返回undefined

//全域作用域
function f1(){ 
    //一級函式作用域
    function f2(){
        //二級函式作用域
    }
}

//全域作用域
var num = 456;

//全域作用域
function f3(){
    //一級函式作用域
    function f4(){
        //二級函式作用域
    }
}

繪製作用鏈

  • 將全域看成一條線,記為0級鏈。
  • 看全域中有什麼成員被宣告(變數、function),若有則以方格形式放在0級鏈上。
  • 看看0級鏈上的function中是否還有function,若有則0級鏈上的function中拉出新的鏈代表1級鏈。
  • 在每一個1級鏈中重複上面行為,以此類推。

https://ithelp.ithome.com.tw/upload/images/20200602/20124767fVG3C9v7uj.png

找尋變數的規則

  1. 先看需要找的變數目前在第幾級鏈上,看該級別鏈上是否有指定的變數,若有則可以直接使用。
  2. 若本級別鏈上沒有找到則往上層找(n-1級鏈),若有直接使用,沒有則再往上層找。
  3. 若一直往上找值到0級鏈(全域)都沒有該變數則返回undefined。
function f1() {
    var num = 123;
    function f2() {
        console.log(num); 
    }
    f2();
}
var num = 456;
f1();  //123

https://ithelp.ithome.com.tw/upload/images/20200602/2012476722FgkGAVKv.png

  • console.log(num)屬於2級鏈,一開始會在同級(2級鏈)中尋找有沒有num這個變數,發現沒有後便往上層(1級鏈)尋找。
  • 到1級鏈中發現有num這個變數則直接使用,於是console出123。

練習

透過上面的介紹,多多少少也了解了作用域與作用域鏈,在網上找一些題目嘗試繪製作用域鏈圖並解答Console的答案。

var num = 123;
function f1() {
    console.log( num ); 
}

function f2() {
    var num = 456;
    f1();
}
f2(); //123

https://ithelp.ithome.com.tw/upload/images/20200607/20124767ljxl9MarHg.png

  • 在f1(0級鏈)中的console.log它存在在1級鏈,雖然在f2中有呼叫f1,但是f1中的console還是存在於1級鏈中,所以會在1級鏈中尋找,發現沒有符合的對象便往上層(0級鏈)找。
  • 到0級鏈中找到對應對象,所以輸出num = 123。

參考資料 :
JavaScript高级讲义


尚未有邦友留言

立即登入留言