JS作用域鏈的詳解

2020-07-16 10:05:04
JavaScript 作用域屬於靜態概念,根據詞法結構來確定,而不是根據執行來確定。作用域鏈是 JavaScript 提供的一套解決識別符號的存取機制—— JavaScript 規定每一個作用域都有一個與之相關聯的作用域鏈。

作用域鏈用來在函數執行時求出識別符號的值。該鏈中包含多個物件,在對識別符號進行求值的過程中,會從鏈首的物件開始,然後依次查詢後面的物件,直到在某個物件中找到與識別符號名稱相同的屬性。如果在作用域鏈的頂端(全域性物件)中仍然沒有找到同名的屬性,則返回 undefined 的屬性值。

在每個物件中進行屬性查詢的時候,還會使用該物件的原型域鏈(後續將會講解原型鏈)。在一個執行上下文,與其關聯的作用域鏈只會被 with 語句和 catch 子句影響。

【範例1】在下面範例中,通過多層巢狀函數設計一個作用域鏈,在最內層函數中可以逐級存取外層函數的私有變數。
var a = 1;  //全域性變數
(function () {
    var b = 2;  //第1層區域性變數
    (function () {
        var c = 3;  //第2層區域性變數
        (function () {
            var d = 4;  //第3層區域性變數
            console.log(a + b + c + d);  //返回10
        }) ()  //直接呼叫函數
    }) ()  //直接呼叫函數
}) ()  //直接呼叫函數
在上面程式碼中,JavaScript 引擎首先在最內層活動物件中查詢屬性 a、b、c 和 d,從中只找到了屬性 d,並獲得它的值(4);然後沿著作用域鏈,在上一層活動物件中繼續查詢屬性 a、b 和 c,從中找到了屬性 c,獲取它的值(3)······以此類推,直到找到所有需要的變數值為止,如圖所示。