摘要:從執(zhí)行上下文的生命周期來說,包括三個部分創(chuàng)建階段執(zhí)行階段執(zhí)行完畢階段。三執(zhí)行完畢階段主要內(nèi)容執(zhí)行完畢后跳出執(zhí)行上下文棧,等待被回收。這就完成了整個的執(zhí)行上下文周期。
關于javascript中的從堆棧內(nèi)存到執(zhí)行上下文
? ? ? ? 先從計算機角度說一下內(nèi)存:內(nèi)存,包括三個部分:只讀存儲器(ROM)、隨機存儲器(RAM)和高速緩沖存儲器(Cache)。
? ? ? ? 而其中,高速緩沖存儲器(Cache)又分為三種:一級緩存(L1 Cache)、二級緩存(L2 Cache)、三級緩存(L3 Cache)。
? ? ? ? 當CPU需要數(shù)據(jù)的時候,就會先找緩存,因為緩存最快,緩存找不到,才去找慢一點的內(nèi)存,然后找到后繼續(xù)將數(shù)據(jù)放入緩存,下次還要的時候,還是先找緩存。
? ? ? ? 簡單來說,緩存中的數(shù)據(jù)只是內(nèi)存的一部分,但是讀寫速度最快,所以CPU先找它。
? ? ? ? 扯遠了,回過頭來。
? ? ? ? 再解釋一下常說的“堆內(nèi)存”、“棧內(nèi)存”,“棧內(nèi)存”也叫做“堆棧內(nèi)存”,不是兩個一起的總稱,實際上就是棧內(nèi)存,所以我這里就分別說“堆內(nèi)存”和“棧內(nèi)存”。
? ? ? ? 這里面就有“堆”和“?!眱蓚€概念了。
? ? ? ? 先說說棧,它是放在是在于一級緩存中的,數(shù)據(jù)被調(diào)用的時候放入存儲空間中,然后被調(diào)用完成時候,就會被立刻釋放。
? ? ? ? 再說堆,它是放在二級緩存中的,它的生命周期由虛擬機的垃圾回收算法來決定。所以調(diào)用這些對象的速度要相對來得低一些。
? ? ? ? 舉個很簡單的例子來解釋“堆”和“?!边@兩個概念:
? ? ? ? 棧,有點像漢諾塔那樣的套圈圈,一圈一圈地放上去,前面放的都被壓在了底部,后面的就壓在上面,一層一層疊羅漢,但是取出來的時候,就是后面放上去的先取出來,越早放進去的越后取出來,簡單來說,就是遲來先上岸。
? ? ? ? 堆,就像是一堆東西那些,就好像你雜亂的房間,一堆雜物,你想找東西,翻來翻去,找到了,可以拿走,有些東西,你不拿走,放在那里,其實就是垃圾。
? ? ? ? 一般來說,javascript中的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,而基本數(shù)據(jù)類型中的變量名和變量直接存放在棧內(nèi)存中,而引用數(shù)據(jù)類型的變量值實際上是存放的一個地址指針,所以它的變量名和變量值也是存放在棧內(nèi)存中,而地址指向的實際內(nèi)容,則是存放在堆內(nèi)存中。
? ? ? ? 好了,開始說一下執(zhí)行上下文了。
? ? ? ? 有些人會混淆執(zhí)行上下文和作用域的概念,后面的文章我會說到作用域和作用域鏈,現(xiàn)在先說執(zhí)行上下文。
? ? ? ? 從執(zhí)行上下文的生命周期來說,包括三個部分:
? ? ? ? 1、創(chuàng)建階段;2、執(zhí)行階段;3、執(zhí)行完畢階段。
? ? ? ? 一、創(chuàng)建階段
? ? ? ? 執(zhí)行上下文是在函數(shù)被調(diào)用的時候才創(chuàng)建,主要有三個內(nèi)容:
? ? ? ? 1、創(chuàng)建變量對象;2、初始化作用域鏈;3、確定this的指向。
? ? ? ? 二、執(zhí)行階段
? ? ? ? 發(fā)生在函數(shù)代碼執(zhí)行階段,主要有三個內(nèi)容:
? ? ? ? 1、變量賦值;2、函數(shù)引用;3、執(zhí)行其他代碼。
? ? ? ? 三、執(zhí)行完畢階段
? ? ? ? 主要內(nèi)容:執(zhí)行完畢后跳出執(zhí)行上下文棧,等待被回收。
? ? ? ? 關于創(chuàng)建階段和執(zhí)行階段的具體內(nèi)容,可能大家會有疑惑,里面的具體內(nèi)容后面文章會慢慢細說。這里單純說說執(zhí)行上下文棧。
? ? ? ? 舉個簡單例子,函數(shù)里面也會有嵌套函數(shù)的情況,就像這樣:
//函數(shù)father function father(age){ var me = age + 20; //函數(shù)son function son(age){ return age; } return son(me); } father(33);
? ? ? ? 既然執(zhí)行上下文是函數(shù)被調(diào)用的時候創(chuàng)建的,那么上面這個father函數(shù)被調(diào)用之后,然后son也被調(diào)用了,那它們的執(zhí)行上下文是什么關系呢?
? ? ? ? 在這里,Javascript會利用執(zhí)行上下文棧(Execution context stack,ECS)來管理執(zhí)行上下文。
? ? ? ? 回想一下前面棧內(nèi)存的概念就很容易理解。
? ? ? ? 當調(diào)用某個函數(shù)的時候,就會創(chuàng)建執(zhí)行上下文,并壓入執(zhí)行上下文棧中,當執(zhí)行完畢的時候,就會從執(zhí)行上下文棧中跳出,等待被回收。像上面這種函數(shù)內(nèi)嵌套函數(shù)的情形,調(diào)用father函數(shù)的時候,father創(chuàng)建的執(zhí)行上下文壓入棧中,然后開始執(zhí)行father的函數(shù)體內(nèi)代碼,因為father函數(shù)還沒執(zhí)行完畢,所以調(diào)用son函數(shù)時候會將son創(chuàng)建的執(zhí)行上下文壓入棧中,當son執(zhí)行完畢,就會跳出,然后father執(zhí)行完畢,繼續(xù)跳出。這就完成了整個father的執(zhí)行上下文周期。
? ? ? ? 還是那句,遲來先上岸的感覺。就好像下面的圖這樣(圖片引用自網(wǎng)絡),下面就是一個執(zhí)行上下文棧,最底層肯定是全局了,然后只要函數(shù)沒執(zhí)行完畢繼續(xù)在函數(shù)內(nèi)調(diào)用其它函數(shù)的話,其它函數(shù)的執(zhí)行上下文就會接著壓上去,最后執(zhí)行完畢,壓在最上面的上下文先清出,然后其它執(zhí)行上下文又變成最上面的了,然后執(zhí)行完畢,繼續(xù)清出,就和圖那樣了。
? ? ? ? 實際情況可能不是圖的那樣簡單,可能清出到EC2那一層的時候,還沒執(zhí)行完這個函數(shù),又調(diào)用其它函數(shù),其它的執(zhí)行上下文又接著壓上去了。
? ? ? ? 當然,道理都是一樣的。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://www.ezyhdfw.cn/yun/84272.html
摘要:作用域的類別可以影響到變量的取值,分為詞法作用域靜態(tài)作用域和動態(tài)作用域。而,采用的就是詞法作用域,或者叫靜態(tài)作用域。 關于javascript中的作用域和作用域鏈 我GitHub上的菜鳥倉庫地址: 點擊跳轉查看其他相關文章 文章在我的博客上的地址: 點擊跳轉 ? ? ? ? 前面的文章說到, 執(zhí)行上下文的創(chuàng)建階段,主要有三個內(nèi)容: ? ? ? ? 1、創(chuàng)建變量對象;2、初始化作用域...
摘要:每次調(diào)用函數(shù)時,都會創(chuàng)建一個新的執(zhí)行上下文。理解執(zhí)行上下文和堆棧可以讓您了解代碼為什么要計算您最初沒有預料到的不同值的原因。 首發(fā):https://www.love85g.com/?p=1723 在這篇文章中,我將深入研究JavaScript最基本的部分之一,即執(zhí)行上下文。在這篇文章的最后,您應該更清楚地了解解釋器要做什么,為什么在聲明一些函數(shù)/變量之前可以使用它們,以及它們的值是如何...
摘要:如果在全局代碼中調(diào)用函數(shù),程序的順序流進入被調(diào)用的函數(shù),創(chuàng)建新的執(zhí)行上下文并將其推送到執(zhí)行堆棧的頂部。每次調(diào)用函數(shù)時,都會創(chuàng)建一個新的執(zhí)行上下文。 翻譯:瘋狂的技術宅鏈接:http://davidshariff.com/blog/... 本文首發(fā)微信公眾號:jingchengyideng歡迎關注,每天都給你推送新鮮的前端技術文章 在這篇文章中,我將深入探討JavaScript的最...
摘要:下面所有的東西都不為堆高我的編程能力,所以我只是把對的認識用最粗鄙的語言進行講解和記錄,所以,閱讀需謹慎執(zhí)行在執(zhí)行之前會先進行編譯。所以對純前端尤其值得一提,不僅要知道怎么進行數(shù)據(jù)類型的轉換更要清楚的知道你當下在操作的是什么數(shù)據(jù)類型。 下面所有的東西都不為堆高我的編程能力,所以我只是把對JS的認識用最粗鄙的語言進行講解和記錄,所以,閱讀需謹慎! JS執(zhí)行 JS在執(zhí)行之前會先進行編譯...
摘要:進階期理解中的執(zhí)行上下文和執(zhí)行棧進階期深入之執(zhí)行上下文棧和變量對象但是今天補充一個知識點某些情況下,調(diào)用堆棧中函數(shù)調(diào)用的數(shù)量超出了調(diào)用堆棧的實際大小,瀏覽器會拋出一個錯誤終止運行。 (關注福利,關注本公眾號回復[資料]領取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實戰(zhàn)、面試指導) 本周正式開始前端進階的第一期,本周的主題是調(diào)用堆棧,今天是第3天。 本計劃一共28期,每期重點攻...
閱讀 624·2021-08-31 09:45
閱讀 1723·2021-08-11 11:19
閱讀 949·2019-08-30 15:55
閱讀 902·2019-08-30 10:52
閱讀 2929·2019-08-29 13:11
閱讀 2993·2019-08-23 17:08
閱讀 2899·2019-08-23 15:11
閱讀 3140·2019-08-23 14:33