1. 程式人生 > >作用域、作用域鏈精解

作用域、作用域鏈精解

首先來幾個名詞解釋:

  • 作用域[scope]:每一個js函式都是一個物件,物件中有些屬性我們可以訪問,但有些不可以,這些屬性僅供js引擎存取,[[scope]]就是物件其中一個屬性。[[scope]]指的就是我們所說的作用域,其中儲存了執行期上下文的集合
  • 作用域鏈:[[scope]]中所儲存的執行期上下文物件的集合,這個集合呈鏈式連結,我們把這種鏈式連結叫做作用域鏈。
  • 執行期上下文:當函式執行時,會建立一個稱為執行期上下文的內部物件(簡稱AO),一個執行期上下文定義了一個一個函式執行時的環境,函式每次執行時對應的執行上下文都是獨一無二的,所以多次呼叫一個函式會導致建立多個執行上下文,當函式執行完畢,它所產生的執行上下文被銷燬;
  • 查詢變數:從作用域鏈的頂端依次向下查詢;

以下面的程式碼塊為例:

function test1() {
            function test2() {
                var test2Num = 234;
            }
            var test1Num = 123;
            test2();
        } 
        var globalNum = 100;
        test1();

test函式是一個物件,所以它一定有[scope]這個屬性。也就是有自己的作用域,當它執行時,有自己的作用域鏈,如下圖1:

從圖中可以看出,每一個函式在執行時都有自己的作用域鏈;其中需要注意的幾是:

  1. 內部的函式會有外部的AO;在內部函式被定義時,會儲存所在的AO;被執行時,會生成自己的AO,並且自己的AO在作用域鏈最前面;
  2. 在不同的時刻呼叫同一個函式生成的AO是不同的;所以每個函式執行時的上下文都是不同的;
  3. 當函式執行完畢,它所產生的執行上下文被銷燬;