定義:
執行上下文是JavaScript程式碼被解析和執行時所在的抽象概念,
執行JavaScript程式碼時,每次當控制器轉到可執行程式碼的時候,就會進入一
個執行上下文。
執行上下文可以理解為當前程式碼的執行環境
複製程式碼
JavaScript中的執行環境:
那麼也對應著三種執行上下文
執行上下文的型別:
全域性執行上下文:
- 預設或者說是基礎的上下文。任何不在函式內部的程式碼都在全域性上下文中。
- 一個程式(頁面)中只有一個,瀏覽器的全域性物件就是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函式的執行上下文壓入呼叫棧中;
接下來,應為changeColor的上下文入棧,控制器將會執行其中的程式碼。當遇到swapColor()的時候,swapColor函式的執行上下文也將建立,隨後,壓入執行棧的棧頂。
當控制器將swapChange中的程式碼進行執行,再沒有遇到其他可以生成其他執行上下文的情況下,swapChange執行完畢。swapChange的上下文將會從執行棧中彈出。
隨後,控制器據需執行changChange中的程式碼,和swapChange’一樣,在執行中沒有再遇到其他可以生成其他執行上下文的情況下,changeColor執行完畢,changeColor的上下文將會從執行棧中彈出。
執行完成之後,執行棧當中就只剩下全域性上下文。
當關閉當前頁面的時候,全域性上下文也將被彈出執行棧
整個的流程就如下圖展示
總結:
單執行緒:就是同個時間段只能做一件任務,完成之後才可以繼續下一個任務。
同步執行:只有棧頂的上下文處於執行狀態,其他上下文都處於等待狀態
全域性上下文只存在一個,在頁面關閉的時候出棧
每次函式被呼叫,都會有新的函式執行上下被建立,即使呼叫的是自身函式也是如此;
附:文中,還有一些相關的知識點沒有進行講述,會在後面的學習中補上的