摘要:根據(jù)順序我們也可以看出來(lái),想要理解作用域鏈,執(zhí)行上下文是我們碰到的第一個(gè)坎。
在我們前面理解了作用域之后,“作用域鏈”這個(gè)概念就產(chǎn)生了。那么作用域鏈?zhǔn)鞘裁匆馑迹质窃趺葱纬傻模男└拍钣嘘P(guān)系,這就是我接下來(lái)幾章想和大家探討的內(nèi)容:執(zhí)行上下文、變量對(duì)象和作用域鏈。根據(jù)順序我們也可以看出來(lái),想要理解作用域鏈,執(zhí)行上下文是我們碰到的第一個(gè)坎。
這一章我們就來(lái)討論一下到底什么是執(zhí)行上下文。
1. 定義當(dāng) JS 引擎開(kāi)始執(zhí)行預(yù)編譯生成的代碼時(shí),就會(huì)進(jìn)入到一個(gè)執(zhí)行上下文(Executable Code - 簡(jiǎn)稱 EC)。
在 ECMA 標(biāo)準(zhǔn)規(guī)范里并沒(méi)有從技術(shù)角度去定義 EC 的具體類型和結(jié)構(gòu),這個(gè)是在實(shí)現(xiàn) ECMAScript 引擎時(shí)需要考慮的問(wèn)題。
但是在邏輯上,我們可以將活動(dòng)的執(zhí)行上下文看成一個(gè)棧結(jié)構(gòu)。棧底部永遠(yuǎn)是全局上下文(global context),而頂部就是當(dāng)前活動(dòng)的執(zhí)行上下文。執(zhí)行到當(dāng)前代碼時(shí),上下文入棧,執(zhí)行完畢后,上下文出棧。
2. 可執(zhí)行代碼有幾種前面說(shuō)到當(dāng)引擎執(zhí)行到可執(zhí)行代碼的時(shí)候,就會(huì)將當(dāng)前上下文壓入上下文棧中。那么可執(zhí)行的代碼又分為幾種?
在這里,我們先假設(shè)定義執(zhí)行上下文棧是一個(gè)數(shù)組:
EC = [];
第一種可執(zhí)行代碼 -- 全局代碼:
全局類型代碼是在加載外部的 js 文件或者本地 標(biāo)簽中的代碼。
注意,在全局代碼中,并不包含定義在全局環(huán)境 function 內(nèi)的代碼。
程序啟動(dòng)后進(jìn)入初始化全局環(huán)境:
EC = [ globalContext ];
第二種可執(zhí)行代碼 -- 函數(shù)代碼:
當(dāng)定義的函數(shù)被執(zhí)行時(shí),就進(jìn)入了函數(shù)代碼,當(dāng)前函數(shù)上下文被壓入 EC 棧中。
注意,在函數(shù)代碼中,也不包含定義在該函數(shù)內(nèi)部環(huán)境 function 內(nèi)的代碼。
例如:
var a = 10; function foo () { var b = 20; foo(); } foo();
這個(gè)例子中的 EC 是什么樣子的呢?
// 初始化 EC = [ globalContext ]; // 第一次調(diào)用 foo 函數(shù) EC = [functionContext, globalContext ]; // 在 foo 內(nèi)遞歸調(diào)用自己 EC = [ functionContext - recursively, functionContext, globalContext ]; // 繼續(xù)遞歸調(diào)用自己 EC = [ ...... functionContext - recursively2, functionContext - recursively, functionContext, globalContext ]; // 遞歸會(huì)不斷調(diào)用下去,因?yàn)闆](méi)有結(jié)束條件,所以這是一個(gè)死循環(huán) // 所以,EC 只會(huì)不斷增加新的上下文,但是卻不會(huì)退出
只有每次 return 的時(shí)候,才會(huì)退出當(dāng)前執(zhí)行上下文,相應(yīng)上下文會(huì)從棧中彈出,棧指針會(huì)自動(dòng)移動(dòng)位置。
注意,當(dāng)函數(shù)沒(méi)有明確指明 return 什么的時(shí)候,默認(rèn) return undefined 。
如果有拋出的異常沒(méi)有被截獲的話,也有可能從一個(gè)或多個(gè)執(zhí)行上下文中退出。當(dāng)所有代碼執(zhí)行完以后,EC 中只會(huì)包含全局上下文(global context),當(dāng)程序退出以后,全局上下文也會(huì)退出。
第三種可執(zhí)行代碼 -- eval 代碼:
eval 函數(shù)在調(diào)用的時(shí)候會(huì)產(chǎn)生上下文。
例如:
eval("var a = 10"); (function foo () { eval("var b = 20"); }()); alert(a); // 10 alert(b); // ReferenceError,b is not defined
這個(gè)例子中 EC 的變化如下:
// 初始化 EC = [ globalContext ]; // eval("var a = 10"); EC = [ evalContext, globalContext ]; // eval 執(zhí)行完畢 EC = [ globalContext ]; // 立即執(zhí)行函數(shù) foo EC = [functionContext, globalContext ]; // eval("var b = 20"); EC = [ evalContext, functionContext, globalContext ]; // eval 執(zhí)行完畢 EC = [ functionContext, globalContext ]; // foo 執(zhí)行完畢 EC = [ globalContext ];
這就是一個(gè)典型的邏輯調(diào)用上下文棧。
在 setTimeout 和 setInterval 函數(shù)中的第一個(gè)參數(shù)也可以傳入代碼字符串,但是這個(gè)一般不會(huì)這么去用,所以這里也就不討論了。
3. 結(jié)論執(zhí)行上下文環(huán)境是我們了解變量對(duì)象和作用域鏈的基礎(chǔ),大家一定要好好理解(其實(shí)也并不難),下一節(jié)我們來(lái)討論變量對(duì)象,相信會(huì)讓大家有一定的收獲。
歡迎關(guān)注我的公眾號(hào)文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/81776.html
摘要:實(shí)現(xiàn)可伸縮的圖片墻中文指南作者簡(jiǎn)介是推出的一個(gè)天挑戰(zhàn)。現(xiàn)在你看到的是這系列指南的第篇。完整指南在從零到壹全棧部落。實(shí)現(xiàn)效果點(diǎn)擊任意一張圖片,圖片展開(kāi),同時(shí)從圖片上下兩方分別移入文字。 Day05 - Flex 實(shí)現(xiàn)可伸縮的圖片墻 中文指南 作者:?liyuechun 簡(jiǎn)介:JavaScript30 是 Wes Bos 推出的一個(gè) 30 天挑戰(zhàn)。項(xiàng)目免費(fèi)提供了 30 個(gè)視頻教程、30 ...
摘要:關(guān)于點(diǎn)擊進(jìn)入項(xiàng)目是我于開(kāi)始的一個(gè)項(xiàng)目,每個(gè)工作日發(fā)布一道面試題。即使這個(gè)時(shí)間周期內(nèi),小明取得多次滿分。創(chuàng)建作用域鏈在執(zhí)行期上下文的創(chuàng)建階段,作用域鏈?zhǔn)窃谧兞繉?duì)象之后創(chuàng)建的。這種一層一層的關(guān)系,就是作用域鏈。 關(guān)于【Step-By-Step】 Step-By-Step (點(diǎn)擊進(jìn)入項(xiàng)目) 是我于 2019-05-20 開(kāi)始的一個(gè)項(xiàng)目,每個(gè)工作日發(fā)布一道面試題。每個(gè)周末我會(huì)仔細(xì)閱讀大家的答...
摘要:關(guān)于點(diǎn)擊進(jìn)入項(xiàng)目是我于開(kāi)始的一個(gè)項(xiàng)目,每個(gè)工作日發(fā)布一道面試題。即使這個(gè)時(shí)間周期內(nèi),小明取得多次滿分。創(chuàng)建作用域鏈在執(zhí)行期上下文的創(chuàng)建階段,作用域鏈?zhǔn)窃谧兞繉?duì)象之后創(chuàng)建的。這種一層一層的關(guān)系,就是作用域鏈。 關(guān)于【Step-By-Step】 Step-By-Step (點(diǎn)擊進(jìn)入項(xiàng)目) 是我于 2019-05-20 開(kāi)始的一個(gè)項(xiàng)目,每個(gè)工作日發(fā)布一道面試題。每個(gè)周末我會(huì)仔細(xì)閱讀大家的答...
摘要:介一回聊狀態(tài)模式,官方描述允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為。有限狀態(tài)機(jī)有限狀態(tài)機(jī)是一個(gè)非常有用的模型,可以模擬世界上大部分事物。這個(gè)是官方說(shuō)法,簡(jiǎn)單說(shuō),她有三個(gè)特征,狀態(tài)總數(shù)是有限的。,任一時(shí)刻,只處在一種狀態(tài)之中。 本回內(nèi)容介紹 上一回聊了聊組合模式(Composite),用組合模式模擬了個(gè)圖片庫(kù),聊了遞歸。介一回聊狀態(tài)模式(State),官方描述允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改...
閱讀 2654·2023-04-25 15:22
閱讀 2824·2021-10-11 10:58
閱讀 1045·2021-08-30 09:48
閱讀 1851·2019-08-30 15:56
閱讀 1730·2019-08-30 15:53
閱讀 1089·2019-08-29 11:16
閱讀 1048·2019-08-23 18:34
閱讀 1638·2019-08-23 18:12