欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

圖解JS執(zhí)行上下文

freeflydom
2024年7月24日 16:36 本文熱度 899

執(zhí)行上下文是什么?

執(zhí)行上下文是一個(gè)抽象的概念,用于描述代碼執(zhí)行時(shí)的環(huán)境,包含了當(dāng)前代碼運(yùn)行時(shí)所需的變量、函數(shù)和參數(shù)。

從一段JS的執(zhí)行談起

單看概念可能還有點(diǎn)懵,其實(shí)執(zhí)行上下文“誕生”的時(shí)機(jī)是JS代碼編譯的時(shí)候,“被操作”的時(shí)機(jī)是JS代碼執(zhí)行的時(shí)候。

什么樣的JS代碼會(huì)被編譯產(chǎn)生執(zhí)行上下文呢?一般來說,有三種情況:

  1. 當(dāng) JavaScript 執(zhí)行全局代碼的時(shí)候,會(huì)編譯全局代碼并創(chuàng)建全局執(zhí)行上下文,而且在整個(gè)頁面的生存周期內(nèi),全局執(zhí)行上下文只有一份。

  2. 當(dāng)調(diào)用一個(gè)函數(shù)的時(shí)候,函數(shù)體內(nèi)的代碼會(huì)被編譯,并創(chuàng)建函數(shù)執(zhí)行上下文,一般情況下,函數(shù)執(zhí)行結(jié)束之后,創(chuàng)建的函數(shù)執(zhí)行上下文會(huì)被銷毀。

  3. 當(dāng)使用 eval 函數(shù)的時(shí)候,eval 的代碼也會(huì)被編譯,并創(chuàng)建eval執(zhí)行上下文

以這段代碼為例:

var a = 2

function add(){

  var b = 10

  return a+b

}

add()

這段代碼很簡單,先是創(chuàng)建了一個(gè) add 函數(shù),接著在代碼的最下面又調(diào)用了該函數(shù)。

那么下面我們就利用圖片來解釋下函數(shù)調(diào)用的過程。

在執(zhí)行到函數(shù) add() 之前,JavaScript 引擎會(huì)為上面這段代碼創(chuàng)建全局執(zhí)行上下文,包含了聲明的函數(shù)和變量,你可以參考下圖:

從圖中可以看出,代碼中全局變量和函數(shù)都保存在全局上下文的變量環(huán)境中。

執(zhí)行上下文準(zhǔn)備好之后,便開始執(zhí)行全局代碼,當(dāng)執(zhí)行到 add 這兒時(shí),JavaScript 判斷這是一個(gè)函數(shù)調(diào)用,那么將執(zhí)行以下操作:

  • 首先,從全局執(zhí)行上下文中,取出 add 函數(shù)代碼。

  • 其次,對(duì) add 函數(shù)的這段代碼進(jìn)行編譯,并創(chuàng)建該函數(shù)的執(zhí)行上下文和可執(zhí)行代碼。

  • 最后,執(zhí)行代碼,輸出結(jié)果。

完整流程你可以參考下圖:

就這樣,當(dāng)執(zhí)行到 add 函數(shù)的時(shí)候,我們就有了兩個(gè)執(zhí)行上下文了——全局執(zhí)行上下文和 add 函數(shù)的執(zhí)行上下文。

也就是說在執(zhí)行 JavaScript 時(shí),可能會(huì)存在多個(gè)執(zhí)行上下文,那么 JavaScript 引擎是如何管理這些執(zhí)行上下文的呢?

答案是通過一種叫棧的數(shù)據(jù)結(jié)構(gòu)來管理的。那什么是棧呢?它又是如何管理這些執(zhí)行上下文呢?

什么是棧

關(guān)于棧,你可以結(jié)合這么一個(gè)貼切的例子來理解,一條單車道的單行線,一端被堵住了,而另一端入口處沒有任何提示信息,堵住之后就只能后進(jìn)去的車子先出來,這時(shí)這個(gè)堵住的單行線就可以被看作是一個(gè)棧容器,車子開進(jìn)單行線的操作叫做入棧,車子倒出去的操作叫做出棧。

在車流量較大的場景中,就會(huì)發(fā)生反復(fù)的入棧、棧滿、出棧、空棧和再次入棧,一直循環(huán)。

所以,棧就是類似于一端被堵住的單行線,車子類似于棧中的元素,棧中的元素滿足后進(jìn)先出的特點(diǎn)。

你可以參考下圖:

什么是 JavaScript 的調(diào)用棧

JavaScript 引擎正是利用棧的這種結(jié)構(gòu)來管理執(zhí)行上下文的。在執(zhí)行上下文創(chuàng)建好后,JavaScript 引擎會(huì)將執(zhí)行上下文壓入棧中,通常把這種用來管理執(zhí)行上下文的棧稱為執(zhí)行上下文棧,又稱調(diào)用棧

為便于你更好地理解調(diào)用棧,下面我們再來看段稍微復(fù)雜點(diǎn)的示例代碼:

var a = 2

function add(b,c){

  return b+c

}

function addAll(b,c){

  var d = 10

  result = add(b,c)

  return a+result+d

}

addAll(3,6)


在上面這段代碼中,你可以看到它是在 addAll 函數(shù)中調(diào)用了 add 函數(shù),那在整個(gè)代碼的執(zhí)行過程中,調(diào)用棧是怎么變化的呢?

下面我們就一步步地分析在代碼的執(zhí)行過程中,調(diào)用棧的狀態(tài)變化情況。

第一步,創(chuàng)建全局上下文,并將其壓入棧底。如下圖所示:

 

從圖中你也可以看出,變量 a、函數(shù) add 和 addAll 都保存到了全局上下文的變量環(huán)境對(duì)象中。全局執(zhí)行上下文壓入到調(diào)用棧后,JavaScript 引擎便開始執(zhí)行全局代碼了。首先會(huì)執(zhí)行 a=2 的賦值操作,執(zhí)行該語句會(huì)將全局上下文變量環(huán)境中 a 的值設(shè)置為 2。設(shè)置后的全局上下文的狀態(tài)如下圖所示:

 

接下來,第二步是調(diào)用 addAll 函數(shù)。當(dāng)調(diào)用該函數(shù)時(shí),JavaScript 引擎會(huì)編譯該函數(shù),并為其創(chuàng)建一個(gè)執(zhí)行上下文,最后還將該函數(shù)的執(zhí)行上下文壓入棧中,如下圖所示:

addAll 函數(shù)的執(zhí)行上下文創(chuàng)建好之后,便進(jìn)入了函數(shù)代碼的執(zhí)行階段了,這里先執(zhí)行的是 d=10 的賦值操作,執(zhí)行語句會(huì)將 addAll 函數(shù)執(zhí)行上下文中的 d 由 undefined 變成了 10。

然后接著往下執(zhí)行,第三步,當(dāng)執(zhí)行到 add 函數(shù)調(diào)用語句時(shí),同樣會(huì)為其創(chuàng)建執(zhí)行上下文,并將其壓入調(diào)用棧,如下圖所示:

 

當(dāng) add 函數(shù)返回時(shí),該函數(shù)的執(zhí)行上下文就會(huì)從棧頂彈出,并將 result 的值設(shè)置為 add 函數(shù)的返回值,也就是 9。如下圖所示:

 

緊接著 addAll 執(zhí)行最后一個(gè)相加操作后并返回,addAll 的執(zhí)行上下文也會(huì)從棧頂部彈出,此時(shí)調(diào)用棧中就只剩下全局上下文了。最終如下圖所示:

 

至此,整個(gè) JavaScript 流程執(zhí)行結(jié)束了。

總結(jié)

  • JavaScript引擎使用調(diào)用棧來管理執(zhí)行上下文。

  • 當(dāng)JavaScript執(zhí)行代碼前,首先遇到全局代碼,會(huì)創(chuàng)建一個(gè)全局執(zhí)行上下文并且壓入執(zhí)行棧中,每當(dāng)遇到一個(gè)函數(shù)調(diào)用,就會(huì)為該函數(shù)創(chuàng)建一個(gè)新的執(zhí)行上下文并壓入棧頂,引擎會(huì)執(zhí)行位于執(zhí)行上下文棧頂?shù)暮瘮?shù),當(dāng)函數(shù)執(zhí)行完成之后,執(zhí)行上下文從棧中彈出,繼續(xù)執(zhí)行下一個(gè)上下文。當(dāng)所有的代碼都執(zhí)行完畢之后,從棧中彈出全局執(zhí)行上下文。


參考資料:《瀏覽器工作原理與實(shí)踐》


作者:一lemon逼
鏈接:https://juejin.cn/post/7381736732445196339
來源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。



該文章在 2024/7/24 16:36:34 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved