1,[[scope]]:每個javascript函數(shù)都是一個對象,對象中有些屬性我們可以訪問,有些屬性我們不能訪問,這些屬性僅供javascript引擎存取,[[scope]]就是其中一個。[[scope]]就是我們所說的作用域,其中存儲了運行期上下文集合(就是作用域鏈)。
2,作用域鏈:[[scope]]作用域中所存儲的執(zhí)行期上下文對象的集合,這個集合呈鏈?zhǔn)芥溄?,我們把這種鏈?zhǔn)芥溄咏凶鲎饔糜蜴湣?br>
3,運行期上下文:當(dāng)函數(shù)執(zhí)行時,會創(chuàng)建一個稱為執(zhí)行期上下文的內(nèi)部對象。一個執(zhí)行期上下文定義了函數(shù)執(zhí)行時的環(huán)境,函數(shù)每次執(zhí)行時,對應(yīng)的執(zhí)行期上下文是獨一無二的,所以多次調(diào)用一個函數(shù)會導(dǎo)致創(chuàng)建多個執(zhí)行期上下文,當(dāng)函數(shù)執(zhí)行完畢,它所產(chǎn)生的執(zhí)行期上下文被銷毀。
4,查找變量的原則:從作用域鏈的頂端依次往下找。
下面以一段代碼分析:
function a(){
function b(){
var b = 234;
}
var a = 123;
b();
}
var glob = 100;
a();
//a函數(shù)在剛剛定義的時候就有屬性a.[[scope]],用于存a的作用域。
//此時里面只有一個第0位指向Global Object,GO里面有this,window等屬性
//當(dāng)a函數(shù)執(zhí)行的時候,會產(chǎn)生一個執(zhí)行期上下文,此時a.[[scope]]會發(fā)生變化,
//第0位裝的是AO對象,第一位裝的是GO對象,此時就構(gòu)成了一個作用域鏈,查找變量的時候就會從頂端的
//第0位依此往下查找。
//b函數(shù)在剛剛定義的時候就有屬性b.[[scope]],用于存b的作用域。
//此時里面只有一個第0位指向a函數(shù)的AO,第一位指向GO
//當(dāng)b函數(shù)執(zhí)行的時候,也會產(chǎn)生一個執(zhí)行期上下文,此時b.[[scope]]會發(fā)生變化,
//第0位裝的是自己的AO對象,第一位裝的是a函數(shù)的AO對象,第二位裝的是GO,此時
//就構(gòu)成了一個自己的作用域鏈
//當(dāng)函數(shù)執(zhí)行完畢的時候作用域鏈被銷毀,所以函數(shù)執(zhí)行完畢的時候外界就無法訪問到函數(shù)內(nèi)部的變量了
下面以圖例說明:



