作用域、作用域鏈精解
阿新 • • 發佈:2018-12-11
首先來幾個名詞解釋:
- 作用域[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:
從圖中可以看出,每一個函式在執行時都有自己的作用域鏈;其中需要注意的幾是:
- 內部的函式會有外部的AO;在內部函式被定義時,會儲存所在的AO;被執行時,會生成自己的AO,並且自己的AO在作用域鏈最前面;
- 在不同的時刻呼叫同一個函式生成的AO是不同的;所以每個函式執行時的上下文都是不同的;
- 當函式執行完畢,它所產生的執行上下文被銷燬;