深入理解閉包(五)——作用域、作用域鏈和執(zhí)行上下文

原文地址:深入理解閉包(五)——作用域、作用域鏈和執(zhí)行上下文

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

作用域

作用域是在代碼編譯階段確定的,一旦代碼寫好,它的作用域就確定了。js中只有兩種作用域,即全局作用域和局部作用域。

全局作用域

如果一個(gè)對(duì)象在代碼的任何一個(gè)地方都可以被訪問到,那么這個(gè)對(duì)象所在的作用域是全局作用域。

  1. 最外層函數(shù)和在最外層函數(shù)外面定義的變量。
  2. 所有末定義直接賦值的變量將被自動(dòng)添加到全局作用域(但是嚴(yán)格模式下,初始化未經(jīng)聲明的變量會(huì)導(dǎo)致錯(cuò)誤)。
  3. 所有window對(duì)象的內(nèi)置屬性,例如window.name、window.location、window.top等等都是全局變量,并且所有屬于全局作用域的變量都是window對(duì)象的屬性。

局部作用域

js中的局部作用域是按照函數(shù)劃分的,因此也稱函數(shù)作用域,其他一些語言是按照花括號(hào){}劃分的,稱為塊級(jí)作用域,區(qū)別如下:

  1. 在Java、C或C++中,花括號(hào){}內(nèi)封閉的代碼塊有自己的作用域,在{}外部無法訪問{}內(nèi)部的變量,這個(gè)作用域就稱為塊級(jí)作用域。
  2. 在javascript中不存在塊級(jí)作用域,而是把每個(gè)函數(shù)作為一個(gè)作用域,在函數(shù)外部無法訪問函數(shù)內(nèi)部的變量。

更多關(guān)于作用域的問題參考這篇文章:理解javascript作用域

執(zhí)行上下文

執(zhí)行上下文就是為代碼執(zhí)行做的準(zhǔn)備工作。主要分為兩類:

  1. 全局執(zhí)行上下文:代碼剛開始運(yùn)行就會(huì)創(chuàng)建的執(zhí)行上下文。
  2. 函數(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ù)的地址引用。

  1. 全局的作用域鏈:由于它只含全局作用域,沒有上級(jí),因此它的作用域鏈只指向本身的全局變量對(duì)象(因?yàn)橹挥幸粋€(gè),甚至可以理解為全局環(huán)境不存在作用域鏈)。查找標(biāo)識(shí)符時(shí)只能從本身的全局變量對(duì)象中查找。
  2. 函數(shù)out的作用域鏈:可以引用函數(shù)out本身的變量對(duì)象以及全局的變量對(duì)象。查找標(biāo)識(shí)符時(shí),先在函數(shù)out變量對(duì)象中尋找,找不到的話再去上一級(jí)全局變量對(duì)象查找。
  3. 函數(shù)inner的作用域鏈:可以引用函數(shù)inner本身的變量對(duì)象和上一級(jí)out函數(shù)的變量對(duì)象以及全局的變量對(duì)象。查找標(biāo)識(shí)符時(shí)依次從inner,out,全局變量對(duì)象中查找。

更多關(guān)于作用域鏈的問題參考這篇文章:理解javascript作用域

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容