重學JavaScript(3)--執行上下文

定義:

執行上下文是JavaScript代碼被解析和執行時所在的抽象概念,
運行JavaScript代碼時,每次當控制器轉到可執行代碼的時候,就會進入一
個執行上下文。
執行上下文能夠理解爲當前代碼的執行環境
複製代碼

JavaScript中的執行環境:

  • 全局環境
  • 函數環境
  • eval函數環境
那麼也對應着三種執行上下文

執行上下文的類型:

  • 全局執行上下文:

    - 默認或者說是基礎的上下文。任何不在函數內部的代碼都在全局上下文中。 
      - 一個程序(頁面)中只有一個,瀏覽器的全局對象就是window對象。
      - 最開始this指向這個全局對象
    複製代碼
  • 函數執行上下文:

    - 當函數被調用的時候被建立,每次調用函數都會建立一個新的執行上下文。
    複製代碼
  • eval執行上下文:

    - 指運行在eval函數中的代碼(使用少,不建議使用)‘
    複製代碼

執行棧

具備 LIFO(後進先出)結構,用於存儲在代碼執行期間建立的全部執行上下文
複製代碼
JavaScript運行時會先進入全局環境,對應的會生成全局上下文。當程序代碼運行到函數時,那麼就會進入函數執行代碼,對應的生成函數的執行上下文。
所以在一個JavaScript程序當中,一定會產生多個執行上下文。而JavaScript引擎會以執行棧(調用棧)的方式來處理他們。

一個正常JavaScript程序運行的執行上下文

首次運行JavaScript代碼的時候,將會建立一個全局的執行上下文並壓入當前的執行棧中。每當發生函數調用的時候,將會爲調用的函數建立一個新的函數執行上下文,並壓入當前執行棧的棧頂。當函數執行完成以後,其對應的函數執行上下文將會從執行棧當中彈出。控制流程將移到被彈出的執行上下文的下一個執行上下文。

用一個例子來理解

var color='blue';
function changeColor(){
    var anotherColor='red';
    function swapColor(){
        var tempColor=anotherColor;
        anotherOther=color;
        color=tempColor;
     }
     swapColor();
}
changeColor();
複製代碼
首先當JavaScript開始執行,最早回建立一個全局的執行上下文,並壓入執行棧中

全局的執行上下文入棧

以後運行到changeColor()(函數聲明時,不會建立執行上下文,只有當函數被調用的時候纔會建立執行上下文),函數changeColor函數的執行上下文建立,將changeColor函數的執行上下文壓入調用棧中;

changColor函數上下文入棧

接下來,應爲changeColor的上下文入棧,控制器將會執行其中的代碼。當遇到swapColor()的時候,swapColor函數的執行上下文也將建立,隨後,壓入執行棧的棧頂。

swapColor函數上下文入棧

當控制器將swapChange中的代碼進行執行,再沒有遇到其餘能夠生成其餘執行上下文的狀況下,swapChange執行完畢。swapChange的上下文將會從執行棧中彈出。

swapColor函數上下文出棧

隨後,控制器據需執行changChange中的代碼,和swapChange’同樣,在執行中沒有再遇到其餘能夠生成其餘執行上下文的狀況下,changeColor執行完畢,changeColor的上下文將會從執行棧中彈出。

changeColor上下文出棧

執行完成以後,執行棧當中就只剩下全局上下文。

執行以後

當關閉當前頁面的時候,全局上下文也將被彈出執行棧
整個的流程就以下圖展現

全局的執行上下文入棧

總結:

單線程:就是同個時間段只能作一件任務,完成以後才能夠繼續下一個任務。
同步執行:只有棧頂的上下文處於執行狀態,其餘上下文都處於等待狀態
全局上下文只存在一個,在頁面關閉的時候出棧
每次函數被調用,都會有新的函數執行上下被建立,即便調用的是自身函數也是如此;
附:文中,還有一些相關的知識點沒有進行講述,會在後面的學習中補上的
相關文章
相關標籤/搜索