1. 程式人生 > 實用技巧 >執行上下文與執行上下文棧

執行上下文與執行上下文棧

執行上下文與執行上下文棧

  • 變數提升與函式提升
    • 變數提升: 在變數var定義(宣告)語句之前, 就可以訪問到這個變數(undefined)
    • 函式提升: 在函式定義語句之前, 就執行該函式
    • 先有變數提升, 再有函式提升
  • 理解
    • 執行上下文: 由js引擎自動建立的物件, 包含對應作用域中的所有變數屬性
    • 執行上下文棧: 用來管理產生的多個執行上下文
  • 分類:
    • 全域性: window
    • 函式(區域性): 對程式設計師來說是透明的
  • 生命週期
    • 全域性 : 準備執行全域性程式碼前產生, 當頁面重新整理/關閉頁面時死亡
    • 函式 : 呼叫函式時產生, 函式執行完時死亡
  • 包含哪些屬性:
    • 全域性 :
      • 用var定義的全域性變數 ==>undefined
      • 使用function宣告的函式 ===>function
      • this ===>window
    • 函式
      • 用var定義的區域性變數 ==>undefined
      • 使用function宣告的函式 ===>function
      • this ===> 呼叫函式的物件, 如果沒有指定就是window
      • 形參變數 ===>對應實參值
      • arguments ===>實參列表的偽陣列
  • 執行上下文建立和初始化的過程
    • 全域性:
      • 在全域性程式碼執行前最先建立一個全域性執行上下文(window)
      • 收集一些全域性變數, 並初始化
      • 將這些變數設定為window的屬性
    • 函式:
      • 在呼叫函式時, 在執行函式體之前先建立一個函式執行上下文
      • 收集一些區域性變數, 並初始化
      • 將這些變數設定為執行上下文的屬性
  • 執行上下文棧
    • 在全域性程式碼執行前, JS引擎就會建立一個棧來儲存管理所有的執行上下文物件
    • 在全域性執行上下文(window)確定後, 將其新增到棧中(壓棧)
    • 在函式執行上下文建立後, 將其新增到棧中(壓棧)
    • 在當前函式執行完後,將棧頂的物件移除(出棧)
    • 當所有的程式碼執行完後, 棧中只剩下window
    var a = 10
    var bar = function (x) {
        var b = 5
        foo(x + b)
    }
    var foo = function (y) {
        var c = 5
        console.log(a + c + y)
    }
    bar(10)
    // bar(10)
    

  • 測試題1
console.log('gb: '+ i)
var i = 1
foo(1)
function foo(i) {
  if (i == 4) {
    return
  }
  console.log('fb:' + i)
  foo(i + 1) //遞迴呼叫: 在函式內部呼叫自己
  console.log('fe:' + i)
}
console.log('ge: ' + i)
  /*
  1. 依次輸出什麼?
    gb: undefined
    fb: 1
    fb: 2
    fb: 3
    fe: 3
    fe: 2
    fe: 1
    ge: 1
  2. 整個過程中產生了幾個執行上下文?  5
  */
  • 測試題2
  /*
   1:先預處理變數, 後預處理函式
   */
  function a() {}
  var a
  console.log(typeof a) // 'function'

  /*
   2:變數預處理, in操作符
   */
  if (!(b in window)) {
    var b = 1
  }
  console.log(b) // undefined

  /*
   3:預處理, 順序執行
   */
  var c = 1
  function c(c) {
    console.log(c)
    var c = 3
  }
  c(2) // 報錯