作用域,作用域鏈,執(zhí)行上下文三者之間有著密切的關(guān)系,相信有一部分人對(duì)這三者只是有一種模糊的概念,今天我們就來理一理,首先我們要回顧一張圖片,由這張圖,你可以清楚地看到這三者分別是在什么時(shí)候創(chuàng)建的,其中又有什么基本的聯(lián)系。

作用域
作用域是在代碼編譯階段確定的,一旦代碼寫好,它的作用域就確定了。js中只有兩種作用域,即全局作用域和局部作用域。
全局作用域
如果一個(gè)對(duì)象在代碼的任何一個(gè)地方都可以被訪問到,那么這個(gè)對(duì)象所在的作用域是全局作用域。
- 最外層函數(shù)和在最外層函數(shù)外面定義的變量。
- 所有末定義直接賦值的變量將被自動(dòng)添加到全局作用域(但是嚴(yán)格模式下,初始化未經(jīng)聲明的變量會(huì)導(dǎo)致錯(cuò)誤)。
- 所有window對(duì)象的內(nèi)置屬性,例如window.name、window.location、window.top等等都是全局變量,并且所有屬于全局作用域的變量都是window對(duì)象的屬性。
局部作用域
js中的局部作用域是按照函數(shù)劃分的,因此也稱函數(shù)作用域,其他一些語言是按照花括號(hào){}劃分的,稱為塊級(jí)作用域,區(qū)別如下:
- 在Java、C或C++中,花括號(hào){}內(nèi)封閉的代碼塊有自己的作用域,在{}外部無法訪問{}內(nèi)部的變量,這個(gè)作用域就稱為塊級(jí)作用域。
- 在javascript中不存在塊級(jí)作用域,而是把每個(gè)函數(shù)作為一個(gè)作用域,在函數(shù)外部無法訪問函數(shù)內(nèi)部的變量。
更多關(guān)于作用域的問題參考這篇文章:理解javascript作用域
執(zhí)行上下文
執(zhí)行上下文就是為代碼執(zhí)行做的準(zhǔn)備工作。主要分為兩類:
- 全局執(zhí)行上下文:代碼剛開始運(yùn)行就會(huì)創(chuàng)建的執(zhí)行上下文。
- 函數(shù)執(zhí)行上下文:函數(shù)被調(diào)用時(shí)創(chuàng)建的執(zhí)行上下文。
執(zhí)行上下文前面兩篇文章已經(jīng)講得非常透徹了,這里也就不再多說了。
更多關(guān)于執(zhí)行上下文的問題參考這兩篇文章:變量對(duì)象 和執(zhí)行上下文棧 。
作用域鏈
作用域鏈本質(zhì)上是一個(gè)指向當(dāng)前環(huán)境與上層環(huán)境的一系列變量對(duì)象的指針列表(它只引用但不實(shí)際包含變量對(duì)象),作用域鏈保證了當(dāng)前執(zhí)行環(huán)境對(duì)符合訪問權(quán)限的變量和函數(shù)的有序訪問。
舉個(gè)栗子:
var a = 1;
function out() {
var b = 2;
function inner() {
var c = 3;
console.log(a+b+c);
}
inner();
}
out();
首先,代碼開始運(yùn)行時(shí)就創(chuàng)建了全局上下文環(huán)境,接著運(yùn)行到out()時(shí)創(chuàng)建out函數(shù)的執(zhí)行上下文,最后運(yùn)行到inner()時(shí)創(chuàng)建inner函數(shù)的執(zhí)行上下文,這三個(gè)執(zhí)行上下文中的變量對(duì)象分別是:

其中,由于函數(shù)調(diào)用時(shí)都沒有傳入?yún)?shù),所以arguments都沒有值,reference表示該函數(shù)的地址引用。
- 全局的作用域鏈:由于它只含全局作用域,沒有上級(jí),因此它的作用域鏈只指向本身的全局變量對(duì)象(因?yàn)橹挥幸粋€(gè),甚至可以理解為全局環(huán)境不存在作用域鏈)。查找標(biāo)識(shí)符時(shí)只能從本身的全局變量對(duì)象中查找。
- 函數(shù)out的作用域鏈:可以引用函數(shù)out本身的變量對(duì)象以及全局的變量對(duì)象。查找標(biāo)識(shí)符時(shí),先在函數(shù)out變量對(duì)象中尋找,找不到的話再去上一級(jí)全局變量對(duì)象查找。
- 函數(shù)inner的作用域鏈:可以引用函數(shù)inner本身的變量對(duì)象和上一級(jí)out函數(shù)的變量對(duì)象以及全局的變量對(duì)象。查找標(biāo)識(shí)符時(shí)依次從inner,out,全局變量對(duì)象中查找。
更多關(guān)于作用域鏈的問題參考這篇文章:理解javascript作用域

