本篇初步介紹作用域的概念及產(chǎn)生過程。
執(zhí)行期上下文
上篇說了函數(shù)在執(zhí)行的前一刻,會進行預(yù)編譯過程,創(chuàng)建一個執(zhí)行期上下文對象:AO或GO。它定義了函數(shù)執(zhí)行期的環(huán)境,且每次調(diào)用都會產(chǎn)生一個新的執(zhí)行期上下文對象,在函數(shù)調(diào)用結(jié)束后,該對象立馬銷毀。
作用域
每個函數(shù)對象都會有一個[[scope]]屬性,該屬性就是函數(shù)的作用域,它存儲了執(zhí)行期上下文的集合,該屬性只能JavaScript引擎調(diào)用。
作用域鏈
[[scope]]中存儲的執(zhí)行期上下文集合呈鏈?zhǔn)浇Y(jié)構(gòu),我們把這種結(jié)構(gòu)叫做作用域鏈。
作用域的生成過程
我們通過如下的一個函數(shù)來分析函數(shù)作用域的生成過程。
首先,a函數(shù)在定義時,會生成如下作用域:
然后,執(zhí)行a函數(shù),生成如下作用域:
a函數(shù)執(zhí)行時,b函數(shù)定義,b定義時,生成如下作用域,從圖中可以看出,b在定義時的作用域直接指向a執(zhí)行時生成的執(zhí)行期上下文,它們共用相同的執(zhí)行期上下文。
b函數(shù)執(zhí)行時,生成如下的作用域:
當(dāng)b執(zhí)行完成后,b的作用域變回到b定義時的狀態(tài),同理,a執(zhí)行完成后,a的作用域也變回到a定義時的狀態(tài)。
通過作用域內(nèi)部保存的作用域鏈,我們可以按照該鏈至頂向下查找變量(也即從函數(shù)內(nèi)部向其外部查找)。