執(zhí)行環(huán)境、作用域、作用域鏈

執(zhí)行環(huán)境(execution context)

執(zhí)行環(huán)境定義了變量或者函數(shù)有權(quán)訪(fǎng)問(wèn)的其他數(shù)據(jù),決定了他們各自的行為。每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象(variable object),環(huán)境中定義的變量和函數(shù)都保存在這個(gè)對(duì)象中。

全局執(zhí)行環(huán)境

全局執(zhí)行環(huán)境是最外圍的一個(gè)執(zhí)行環(huán)境。在web瀏覽器中,全局執(zhí)行環(huán)境被認(rèn)為是window對(duì)象。某個(gè)執(zhí)行環(huán)境中的所有代碼被執(zhí)行完畢之后,該環(huán)境被銷(xiāo)毀,保存在其中的所有變量和函數(shù)定義也隨之銷(xiāo)毀。(全局執(zhí)行環(huán)境直到應(yīng)用程序退出----例如關(guān)閉網(wǎng)頁(yè)或者瀏覽器時(shí)才會(huì)被銷(xiāo)毀)

執(zhí)行環(huán)境

每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。當(dāng)執(zhí)行流進(jìn)入到一個(gè)函數(shù)時(shí),函數(shù)的環(huán)境會(huì)被推入到一個(gè)環(huán)境棧中。而在這個(gè)函數(shù)執(zhí)行之后,棧將其環(huán)境彈出,把控制權(quán)返回給之前的執(zhí)行環(huán)境。
執(zhí)行環(huán)境始終是this關(guān)鍵字的值,它是擁有當(dāng)前所執(zhí)行代碼的對(duì)象的引用,函數(shù)的每次調(diào)用都會(huì)創(chuàng)建一個(gè)新的執(zhí)行環(huán)境。
ps:代碼在下面的例子中


作用域鏈

當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí),會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈(scope chain)。
作用域鏈的用途,是保證對(duì)執(zhí)行環(huán)境有權(quán)訪(fǎng)問(wèn)的所有變量或者函數(shù)有序訪(fǎng)問(wèn)。
(1) 作用域鏈的前端,始終都是當(dāng)前執(zhí)行的代碼所在環(huán)境的變量對(duì)象。如果這個(gè)環(huán)境是函數(shù),則將其活動(dòng)對(duì)象(activation object)作為變量對(duì)象?;顒?dòng)對(duì)象在最開(kāi)始時(shí)只包含一個(gè)變量,即arguments對(duì)象(這個(gè)對(duì)象在全局環(huán)境中是不存在的)。
(2) 作用域鏈中的下一個(gè)變量對(duì)象來(lái)自包含(外部)環(huán)境,而在下一個(gè)變量對(duì)象則來(lái)自下一個(gè)包含環(huán)境。這樣一直延續(xù)到全局執(zhí)行環(huán)境。
(3) 全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈中的最后一個(gè)對(duì)象。
(4) 標(biāo)識(shí)符解析是沿著作用域鏈一級(jí)一級(jí)的搜索標(biāo)識(shí)符的過(guò)程。搜索過(guò)程始終從作用域鏈的前端開(kāi)始,然后逐級(jí)的向后回溯,直至找到標(biāo)識(shí)符為止。如果找不到標(biāo)識(shí)符,通常會(huì)導(dǎo)致錯(cuò)誤發(fā)生。
(5) 在局部作用域中定義的變量可以在局部環(huán)境中與全局變量互換使用。

例子

  function fn1(){
    var a = 1;
    return function fn2(){
        return a;
    }
  }
  var b = fn1()
  var c = b() //1
執(zhí)行環(huán)境、變量對(duì)象、作用域鏈之間的關(guān)系

上圖體現(xiàn)執(zhí)行環(huán)境、作用域鏈和變量對(duì)象(活動(dòng)對(duì)象)之間的關(guān)系。調(diào)用fn1返回函數(shù)fn2 ,fn2內(nèi)部訪(fǎng)問(wèn)了fn1中定義的a,當(dāng)fn2調(diào)用時(shí)返回a=1,但是fn2中沒(méi)有定義1,所以會(huì)順著作用域鏈向上找,直至找到a,沒(méi)有則報(bào)錯(cuò)。

因?yàn)檫@里應(yīng)用了閉包,當(dāng)fn1執(zhí)行結(jié)束,fn1的執(zhí)行環(huán)境會(huì)銷(xiāo)毀,但是由于a被fn2訪(fǎng)問(wèn),所以fn1作用域鏈會(huì)斷開(kāi),但是變量對(duì)象保留,供fn2訪(fǎng)問(wèn)。

?著作權(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)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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