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

Hustry發表於2019-04-04

定義:

執行上下文是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上下文出棧

執行完成之後,執行棧當中就只剩下全域性上下文。

執行之後

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

全域性的執行上下文入棧

總結:

單執行緒:就是同個時間段只能做一件任務,完成之後才可以繼續下一個任務。
同步執行:只有棧頂的上下文處於執行狀態,其他上下文都處於等待狀態
全域性上下文只存在一個,在頁面關閉的時候出棧
每次函式被呼叫,都會有新的函式執行上下被建立,即使呼叫的是自身函式也是如此;
附:文中,還有一些相關的知識點沒有進行講述,會在後面的學習中補上的

相關文章