js執行上下文 一,執行上下文的類型 二,執行上下文的生命週期

執行上下文(Execution Context):函數執行前進行的準備工作(也稱執行上下文環境)。

當執行代碼進入一個環境時,就會爲該環境創建一個執行上下文,它會做一些準備工作,如變量提升,確定作用域等。


一,執行上下文的類型

js中有三種執行上下文類型:

全局執行上下文:頂層上下文,任何不在函數內部的代碼都在其中。上下文中的大哥大!它幹了兩件事:1.創建一個全局的window對象(瀏覽器環境下),2.設置this的值等於這個全局對象。(一個程序中只會有一個全局執行上下文)

函數執行上下文:函數被調用時,會創建新的上下文,可以有多個。

Eval函數執行上下文:aval函數專用,用的不多,沒排面,不討論。

執行棧

在js中,通過棧的存取方式來管理執行上下文,我們可稱其爲執行棧,或函數調用棧(Call Stack)。

棧遵循“先進先出,後進後出”的規則,也就是LIFO(Last In First Out)規則,可以用乒乓球盒子來類比理解。

特點:

1,先進先出,後進後出

2,出口在頂部,且僅有一個

當js引擎第一次遇到你的腳本時,它會創建一個全局的執行上下文並且壓入當前執行棧。而每當引擎遇到一個函數調用,它會爲該函數創建一個新的執行上下文並壓入棧的頂部。

引擎會執行那些位於執行上下文頂棧頂的函數,當函數執行結束時,其執行上下文從棧中彈出,控制流程達到當前棧中的下一個上下文。

我們可以通過示例代碼來理解:


function foo () {

   function bar () {

       return 'I am bar';

   }

   return bar();

}

foo();

二,執行上下文的生命週期

執行上下文的生命週期有兩個階段:

創建階段(進入執行上下文,如:變量提升等)

執行階段

創建階段的操作:

1,創建變量對象

函數環境會初始化創建Arguments對象(並賦值),並傳遞長度length

匿名函數聲明(並賦值)

1,變量聲明,函數表達式聲明(未賦值,即變量提升)

2,確定this指向(this由調用者確定)

3,確定作用域(詞法環境確定,哪裏聲明,哪裏確定)

執行階段的操作

1,變量對象賦值

變量賦值

函數表達式賦值

2,調用函數

3,執行其他代碼片段

值得注意的是,執行上下文可存在多個,因此在遞歸中可能因爲沒有終止條件而造成死循環,堆棧溢出錯誤。

// 遞歸調用自身

function foo() {

 foo();

}

foo();

// 報錯: Uncaught RangeError: Maximum call stack size exceeded

文末總結:

1,js是單線程

2,棧頂的執行上下文處於執行中時,其他的需要排隊

3,處於底部的總是全局上下文,關閉頁面時出棧

4,函數執行上下文可存在多個,但應避免遞歸時堆棧溢出

5,函數調用時就會創建新的上下文,即使調用自身,同樣如此

參考文檔:

https://mp.weixin.qq.com/s/lAvyjfBZvX0E50QiW3aW7w

https://juejin.im/post/5ba32171f265da0ab719a6d7(並未討論其中的詞法環境)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章