標籤:exe pre log 初始化 div 靜態 哪些 如何 execution
一直一來,對JavaScript的代碼執行順序,大部分人都會認為 順序執行
var foo = function () { console.log(‘foo1‘);}foo(); // foo1var foo = function () { console.log(‘foo2‘);}foo(); // foo2
這裡看起來似乎都很合理,但是 沒有想象的那麼簡單
在看這一段代碼
function foo() { console.log(‘foo1‘);}foo(); function foo() { console.log(‘foo2‘);}foo();
兩次都會列印出foo2
這裡涉及到兩個問題 變數提升(之前寫過) 函數提升
JavaScript引擎並不是一行一行分析 執行程式 而是一段一段的執行 ,當執行一段代碼的時候,會進行一個“準備工作”,變數提升 函數提升 就是準備工作
這一段一段JavaScript是怎麼劃分的?
可執行代碼
這就要說到 JavaScript 的可執行代碼(executable code)的類型有哪些了?
就三種,全域代碼、函數代碼、eval代碼(逸出字元串為對象)。
舉個例子,當執行到一個函數的時候,就會進行準備工作,這裡的“準備工作”,
讓我們用個更專業一點的說法,就叫做"執行內容(execution context)"。
執行內容棧
接下來問題來了,我們寫的函數多了去了,如何管理建立的那麼多執行內容呢?
所以 JavaScript 引擎建立了執行內容棧(Execution context stack,ECS)來管理執行內容
為了類比執行內容棧的行為,讓我們定義執行內容棧是一個數組:
ECStack = [];
試想當 JavaScript 開始要解釋執行代碼的時候,最先遇到的就是全域代碼,
所以初始化的時候首先就會向執行內容棧壓入一個全域執行內容,
我們用 globalContext
表示它,並且只有當整個應用程式結束的時候,
ECStack 才會被清空,所以程式結束之前, ECStack 最底部永遠有個 globalContext:
ECStack = [ globalContext //全域代碼];
現在 JavaScript 遇到下面的這段代碼了:
function fun3() { console.log(‘fun3‘)}function fun2() { fun3();}function fun1() { fun2();}fun1();
既然是棧,必定是先進後出 上面這段代碼可以這樣處理
//上面代碼執行完畢//遇到fun1執行 加入棧ECStack.push(<fun1> functionContext);//fun1裡面執行fun2 加入棧ECStack.push(<fun2> functionContext);//fun1裡面執行fun2裡面執行fun3 加入棧 ECStack.push(<fun3> functionContext);//fun3裡面執行代碼 fun3 彈出棧ECStack.pop();//fun2 執行完畢 彈出棧ECStack.pop();//fun1 執行完畢 彈出棧ECStack.pop();// javascript接著執行下面的代碼,但是ECStack底層永遠有個globalContext
解答思考題
上一篇部落格講了靜態範圍的問題,那麼使用 執行內容棧的怎麼處理呢?
var scope = "global scope";function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f();}checkscope();
ECStack.push(<checkscope> functionContext);ECStack.push(<f> functionContext);ECStack.pop();ECStack.pop();
var scope = "global scope";function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f;}checkscope()();
ECStack.push(<checkscope> functionContext);ECStack.pop();ECStack.push(<f> functionContext);ECStack.pop();
雖然結果一樣但是代碼的執行卻並不一樣
為了更詳細講解兩個函數執行上的區別,我們需要探究一下執行內容到底包含了哪些內容
今後更新
---恢複內容結束---
JavaScript執行內容