執行上下文通常有三種,全局執行上下文、函數執行上下文、eval 執行上下文瀏覽器
全局執行上下文只有一個,在客戶端裏是瀏覽器本身建立的,就是咱們常常能碰見的 window 對象
全局執行上下文會有大量的方法,屬性,也是咱們全局變量和函數定義的載體。函數
在執行全局代碼以前,
全局執行上下文會對代碼進行預處理:this
* var 定義的變量賦值爲 undefined,而且被 window 收錄爲屬性 * 全局聲明的 function 函數,被 window 收錄爲方法
作完這些之後開始執行全局代碼spa
函數執行上下文會出現比較多,具體何時出現呢?
函數執行上下文在準備調用函數,執行函數體的內容以前被建立code
這時函數執行上下文也會對局部數據處理對象
* 形參變量被賦值,被函數執行上下文收錄爲屬性 * arguments 賦值實參列表,被函數上下文收錄爲屬性 * var 聲明的變量,被賦值 undefined,被函數上下文收錄爲屬性 * function 聲明的函數賦值,被收錄爲方法 * this 賦值爲調用函數的對象
作完以上內容,就開始執行函數內局部代碼blog
可是這麼多的執行上下文,放在哪裏呢?通常語言都講究容器,像棧內存,堆內存都是爲了存放數據而生,因此執行上下文都存放在執行棧裏內存
它是用來存儲代碼執行以前建立的各類棧,有先進後出的特性rem
在代碼首次運行的時候,瀏覽器會建立一個全局執行上下文棧,放到調用棧中(即壓棧),而後當每次碰見調用函數的時候,建立的函數執行上下文棧依次壓棧,執行完一個函數就會出棧一個上下文,直到最後仍是有個全局上下文棧在最低部it
咱們來看看下面代碼的打印順序
function fun1() { fun2(); console.log('fun1'); }; function fun2() { fun3(); console.log('fun2'); }; function fun3() { console.log('fun3'); }; fun1(); // fun3 fun2 fun1
結果中咱們能看到:fun三、fun二、fun1
這就是咱們所說的,遇到函數調用就建立函數上下文壓棧,而且棧中內容先進後出,fun一、fun二、fun3 順次壓棧,出棧順序就會反過來。
總結