JavaScript 是如何工做的系列——第三篇
在上篇文章《JavaScript 引擎(V8)是如何工做的》中,咱們介紹了 JavaScript 引擎(V8)是如何執行 JavaScript 代碼的。本篇文章將開始介紹 JavaScript 執行機制中的核心概念——執行上下文。javascript
執行上下文(Execution Context),也稱爲執行環境,就是當前 JavaScript 代碼執行時所在環境的抽象概念。前端
每當開始執行代碼時,JavaScript 引擎會爲整個程序建立一個執行上下文(全局執行上下文),JavaScript 代碼都是在執行上下文中運行的。java
在 JavaScript 中,執行環境主要分爲:git
咱們看一個例子:github
var a = 'Hello World!' function helloWorld () { var a = 'Hello Function!' console.log(a) } helloWorld() console.log('a)
上述代碼,建立的執行上下文結構以下圖所示:
segmentfault
顯而易見,在一個 JavaScript 程序中,一般狀況下都會存在多個執行上下文,那麼這些執行上下文是如何管理的呢?數組
JavaScript 引擎建立了執行上下文棧(Execution Context Stack) 來管理執行上下文。瀏覽器
首先咱們來了解下什麼是棧數據結構?數據結構
棧中數據的存取方式相似給槍上子彈,先上的子彈最後打出,後上的子彈先打出。
特色:先進後出,後進先出函數
瞭解了棧數據結構後,咱們繼續來講執行上下文棧是如何管理執行上下文的?
咱們用數組來模擬執行上下文棧的行爲:ECStack = [];
。
function fn2() { console.log('fn2') } function fn1() { console.log('fn1') fn2(); } fn1();
上述這段代碼在執行過程當中,執行上下文棧的行爲是什麼樣的?咱們來分析一下:
ECStack.push(global_EC);
ECStack.push(fn1_EC);
ECStack.push(fn2_EC);
ECStack.pop();
ECStack.pop();
ECStack.pop();
總結:
在每一個執行上下文中,都包括三個重要的屬性:(ES3版,ES5後作了一些變動,具體變化內容後續會寫文章總結)
僞代碼以下:
global_EC = { scopeChain: { // Current scope + scopes of all its parents }, variableObject: { // All the variables including inner variables & functions, function arguments }, this: {} }
下篇文章將開始介紹 JavaScript 的做用域,以及執行上下文中的做用域鏈,敬請期待。
參考:
JavaScript深刻之執行上下文
前端基礎進階(二):執行上下文詳細圖解
JS 執行環境、做用域鏈、活動對象
The Journey of JavaScript From Downloading Scripts to Execution – Part III