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