1. 程式人生 > 其它 >JS 執行上下文的一次理解

JS 執行上下文的一次理解

執行上下文

執行上下文概念

  • 當代碼執行時,會產生一個對應的執行環境,在這個環境中,所有var定義的變數會被事先提出來(變數提升),const和let 定義的變數只能在定義之後使用,程式碼從上往下開始執行,就叫做執行上下文。

注:在定義變數是未直接賦值,使用預設值 undefined。

在 JavaScript 的世界裡,執行環境有三種,分別是:

  1. 全域性環境:程式碼首先進入的環境
  2. 函式環境:函式被呼叫時執行的環境
  3. eval函式

執行上下文特點

  1. 單執行緒,在主程序上執行

  2. 同步執行,從上往下按順序執行

  3. 全域性上下文只有一個,瀏覽器關閉時會被彈出棧

  4. 函式的執行上下文沒有數目限制

  5. 函式每被呼叫一次,都會產生一個新的執行上下文環境

執行上下文棧

  執行全域性程式碼時,會產生一個執行上下文環境,每次呼叫函式都又會產生執行上下文環境。當函式呼叫完成時,這個上下文環境以及其中的資料都會被消除,再重新回到全域性上下文環境。處於活動狀態的執行上下文環境只有一個。

執行上下文生命週期

執行上下文共分3個階段,分別是:

  1. 建立階段

     1. 生成變數物件(全域性物件)

     2. 建立作用域鏈

     3. 確定 this 指向

  2. 執行階段

     1.變數呼叫賦值

     2.函式引用,建立新的執行上下文環境

     3.執行其他程式碼

  3. 銷燬階段

執行完畢退出執行棧,等待回收被銷燬

變數物件

  • 變數物件是與執行上下文相關的資料作用域,儲存了上下文中定義的變數和函式宣告。

  • 變數物件式一個抽象的概念,在不同的上下文中,表示不同的物件:

  1. 全域性執行上下文的變數物件
  •   全域性執行上下文中,變數物件就是全域性物件。
    
  •   在頂層js程式碼中,this指向全域性物件,全域性變數會作為該物件的屬性來被查詢。在瀏覽器中,window就是全域性物件。
    
  1. 函式執行上下文的變數物件
  •   函式上下文中,變數物件VO就是活動物件AO。
    
  •   初始化時,帶有arguments屬性。
    
  •   函式程式碼分成兩個階段執行
    
  •   進入執行上下文時,此時變數物件包括
    
  •   形參
    
  •   函式宣告,會替換已有變數物件
    
  •   變數宣告,不會替換形參和函式
    
  •   函式執行
    

列子

var a = 1, b, fn = function() {
    console.log(a)
    var a = 3,b = 2;
    bar(b)
}
var bar = function(x) {
    return x + 4;
}
fn()
  • 執行結果 undefined
  • JS 是單執行緒,從上到下執行每一行程式碼
  1. 建立變數a並賦值1,變數b 沒有賦值,使用 undefined 預設值,fn 賦值函式,bar 賦值函式
  2. 呼叫 fn(), fn 進入執行棧,建立新的 fn 內部執行上下文。列印 a 此時 在 fn作用域內,定義了一個新的變數 a,但是在使用a是 a並沒有賦值,所以 列印a, 輸出:undefined。程式碼向下執行,a,b分別賦值。呼叫函式bar()
  3. 函式bar進入執行棧,開始執行, 返回結果,出棧內部等待銷燬回收。
  4. fn() 退出執行棧,等待銷燬回收
  5. 回到全域性執行環境(全域性上下文)