深刻理解javascript系列(三):執行上下文

JavaScript代碼在執行時會進入一個運行環境,這是咱們都知道的。這種運行環境咱們也叫作執行上下文(Execution Context)。javascript

javascript中常見的運行環境有三種:java

一、全局環境:代碼運行首先進入的就是全局環境。瀏覽器

二、函數環境:當函數運行時,就會進入當前函數中執行代碼。bash

三、eval環境:不作解釋,能夠參考《你不知道javascript上》。閉包

所以能夠預見的是,在一段javascript代碼運行時,一定會有很多運行環境的出現。函數

javascript引擎會以棧的方式來處理這些運行環境,這個棧,就是call stack(函數調用棧)。call stack規定javascript代碼執行的順序。棧底永遠都是全局上下文(全局環境),棧頂則是當前正在執行的上下文。工具

當代碼遇到以上幾種狀況,都會生產執行上下文並進入call stack。處於棧頂的執行上下文執行完畢後會自動退出call stack。(這也符合了咱們所說的棧的「兵乓球盒模型」)。學習

爲了清晰的看到整個代碼執行的過程,咱們經過幾個實例來了解call stack的規則。ui

爲了方便學習js核心,推薦這個工具:latentflip.com/loupe。簡直六的不行!
this

3.1  實例1

var color = 'blue';
function changeColor() {
    var anotherColor = 'red';
    
    function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
    }
    swapColors();
}

changeColor();
複製代碼

在咱們開始瞭解以前,咱們應該本身內心先把流程跑一遍。

好了,如今開始

第一步全局上下文入棧,並一直存於棧底。(因爲loupe工具沒有顯示全局環境,因此這裏就不上圖了。

第二步,全局上下文入棧後,從可執行代碼開始執行(在代碼執行以前還有些活動,我稍後系列中會作筆記),直到遇到了changeColors(),這句代碼激活了函數changeColors,從而建立了本身的執行上下文。於是此時是changeColorsEC的上下文入棧。以下圖所示:


 第三步,changeColorsEC的上下文入棧後,開始執行可執行的代碼,當遇到swapColors()這句代碼時激活了swapColors的執行上下文。所以第三步就是changeColorsEC的上下文入棧。以下圖所示:


第四步,在swapColors的可執行代碼中,沒有其餘能生成執行上下文的狀況,所以這段代碼順利結束本身,他會從call stack中彈出。

第五步,在swapColors的執行上下問彈出後,在changeColors執行上下文中,繼續執行可執行的代碼,沒有在遇到其它的執行上下文,順利彈出。這樣整個,call stack中就只剩下全局上下文了。

最後,關閉瀏覽器窗口,全局上下文彈出棧。



3.2  實例2

function f1() {
    var n = 999;
    function f2() {
        alert(n);
    }
    return f2;
}
var result = f1();
result();
複製代碼

這是一個簡單的閉包實例,咱們只需根據「函數執行時,執行上下文被激活」。這一原則繼續在咱們內心走一遍代碼執行過程。

第一步仍然是全局上下文入棧。

第二步,執行可執行的代碼,當遇到f1()時,f1的執行上下被激活,併入棧。

第三步,在f1中執行可執行的代碼,沒有可執行的上下文,彈出棧來。

第四步,繼續在全局上下文中,執行可執行的代碼,這個時候遇到了result(),result()會建立一個的新的上下文(被激活),所以這時result的上下文入棧。

第五步,這個result()其實就是在f1中聲明的函數f2,所以這個時候會執行f2中的代碼。因爲在f2中沒有產生新的上下文,所以執行完畢後直接出棧。

3.3  生命週期

咱們知道,當一個函數調用時,一個新的執行上下會被建立。一個執行上下文的生命週期大體能夠分爲兩個階段:建立階段和執行階段

建立階段

在這個階段,執行上下文會分別建立變量對象,確認做用域鏈,以及肯定this的指向。

執行階段

建立階段以後,就開始執行代碼,這個時候會完成變量賦值、函數引用、以及執行其它可執行的代碼。


從執行上下文的生命週期能夠看到它的重要性,其中涉及了變量對象、做用域鏈、this等許多重要但並不容易搞清楚的概念,這些概念有助於咱們真正理解javascript代碼的運行機制。我會在以後的系列中持續上傳個人學習筆記。@陽波大神

記住:執行上下文(全局、函數)、函數激活會幹嗎?、執行上下文的生命週期

相關文章
相關標籤/搜索