JS底層知識理解之執行上下文篇

JS底層知識理解之執行上下文篇html

1、什麼是執行上下文(Execution Context)數組

  執行上下文能夠理解爲當前代碼的執行環境,它會造成一個做用域。瀏覽器

2、JavaScript引擎會以什麼方式去處理多個EC函數

    答案:堆棧。this

  堆棧底部永遠都是全局上下文(Global Context),而頂部就是當前(活動的)執行上下文。堆棧在EC類型進入和退出上下文的時候被修改(推入或彈出)。spa

//其實,這裏能夠將堆棧看做一個數組 
ECStack = [];
//數組的最後一項 
ECStack[ECStack.length - 1] = 全局上下文;
//數組的第一項 
ECStack[0] = 當前的執行上下文;

3、EC的分類.net

一、全局ECcode

    JavaScript代碼運行起來會首先進入該環境。htm

    全局代碼是在"程序"級處理的:例如加載外部的js文件或者本地<script></script>標籤內的代碼,並不包括任何function體內的代碼。對象

  【全局上下文只有惟一的一個,直到應用程序退出,保存在其中的全部變量和函數定義纔會被銷燬】

//在初始化(程序啓動)階段,ECStack是這樣的:
ECStack = [
  globalContext
];

 

二、函數EC

  當函數被調用執行時,會進入當前函數中執行代碼;函數執行環境中的全部代碼執行完畢後,該環境被銷燬,保存在其中的全部變量和函數定義也隨之銷燬。

  當進入 function 函數代碼(全部類型的funtions)的時候,ECStack 被壓入新元素。

tips:

一、具體的函數代碼不包括內部函數(inner functions)代碼

二、同步執行,只有棧頂的上下文處於執行中,其餘上下文須要等待

三、函數中,遇到 return語句 能直接終止 可執行代碼(Execution Code) 的執行,所以會直接將 當前EC 彈出棧

(相似於數組中的 shift() 方法,由於所彈出的當前EC是ECStack[0]);

四、相關代碼執行完之後,ECStack只會包含 全局上下文,一直到整個應用程序結束。

五、每次某個函數被調用,就會有個新的執行上下文爲其建立,即便是調用的自身函數,也是如此

六、函數的執行上下文的個數沒有限制

// 例子
(function foo(bar) { if (bar) { return; } foo(true); })(); // 第一次foo的激活調用 ECStack = [ <foo> functionContext, globalContext ]; // foo的遞歸激活調用 ECStack = [ <foo> functionContext – recursively(遞歸的意思), <foo> functionContext, globalContext ];

4、EC的生命週期

  第一階段:EC建立階段

一、建立變量對象(Variable Object)

二、創建做用域鏈

三、肯定 this 的指向

  第二階段:EC執行階段

一、變量對象轉化爲活動對象 (VO -----》AO)(只在函數環境下才有這個轉化)

二、變量賦值

三、函數引用

四、執行其餘代碼

5、例子簡析

例1:

var color = 'blue';

function changeColor() {
    var anotherColor = 'red';

    function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
    }

    swapColors();
}

changeColor();

EC的入棧出棧整個過程能夠描述爲:「先進後出,後進先出」。

一、全局上下文入棧

二、changeColor的執行上下文入棧

三、swapColors的執行上下文入棧

四、swapColors的執行上下文出棧

五、changeColor的執行上下文出棧

六、全局上下文在瀏覽器窗口關閉後出棧

例2:

function outer(){
    var n=999;
    function inner(){
        alert(n); 
    }
    return inner;
}
var result=outer();
result(); // 999

一、全局上下文入棧

二、outer的執行上下文入棧

三、outer的執行上下文出棧

四、inner的執行上下文入棧

五、inner的執行上下文出棧

六、全局上下文在瀏覽器窗口關閉後出棧

 

注意:由於 outer 中的函數 inner 在 outer 的可執行代碼中,並無被調用執行,所以執行 outer 時,inner 不會建立新的上下文,而直到 resul t執行時,才建立了一個新的執行上下文。

 

參考博文:

  http://blog.csdn.net/pingfan592/article/details/55189804

  http://www.cnblogs.com/TomXu/archive/2012/01/13/2308101.html

相關文章
相關標籤/搜索