JS 核心之 執行上下文和執行上下文棧

執行上下文通常有三種,全局執行上下文、函數執行上下文、eval 執行上下文瀏覽器

1. 全局執行上下文

全局執行上下文只有一個,在客戶端裏是瀏覽器本身建立的,就是咱們常常能碰見的 window 對象
全局執行上下文會有大量的方法,屬性,也是咱們全局變量和函數定義的載體。函數

在執行全局代碼以前,
全局執行上下文會對代碼進行預處理:this

* var 定義的變量賦值爲 undefined,而且被 window 收錄爲屬性
* 全局聲明的 function 函數,被 window 收錄爲方法

作完這些之後開始執行全局代碼spa

2. 函數執行上下文

函數執行上下文會出現比較多,具體何時出現呢?
函數執行上下文在準備調用函數,執行函數體的內容以前被建立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 順次壓棧,出棧順序就會反過來。

總結

  • 全局執行上下文只有一個,代碼執行前由瀏覽器建立
  • 函數執行上下文在函數調用的時候建立
  • 全部的執行上下文存放在調用棧裏,符合先進後出原則
  • var 聲明的變量被賦值 undefined,而且收錄變爲所在上下文的屬性,let、const就沒有收錄,因此 var 建立的變量會提高
  • this 是被調用函數的對象肯定的,沒有調用函數的對象,它就指向 window
相關文章
相關標籤/搜索