JavaScript執行上下文的生命週期

執行上下文的生命週期

    大體分爲兩個階段

    建立階段

            在這個階段,執行上下文會分別建立變量對象,確認做用域鏈,以及肯定this的指向javascript

    執行階段

            完成變量賦值,函數引用,以及執行其餘代碼java

變量對象(VO)

    JavaScript代碼中聲明的全部變量都保存在變量對象中,除此以外,變量對象還可能包含如下內容函數

  • 函數的說有參數(Firefox中爲參數對象arguments)
  • 當前上下文的全部函數聲明(經過function聲明的函數)
  • 當前上下文中全部變量聲明(經過var聲明的變量)

    變量對象的建立過程

  1. 函數的參數變量及其值
  2. 依次獲取當前上下文中全部的函數聲明,例如: foo:<foo reference>
  3. 依次獲取當前上下文中的變量聲明(經過var聲明的變量),屬性值會先被賦值爲undefined,若是該變量名跟函數名同樣,那麼爲了防止同名的函數被修改成undefined,則會跳過,原屬性值不會被修改.(let/const是在執行上下文執行階段開始執行的,避免了變量提高帶來的影響)

實例分析

基於全局上下文分析this

//=========
//demo1.js
var a = 30
//第一步
var a = undefined
//第二步
a = 30
//=========




//=========start====
//demo2.js
var a = 20
function fn(){console.log('fn')}
function fn(){console.log('cover fn')}
function a() {console.log('cover a')}

console.log(a)
fn()

var fn = 'I want cover function named fn.'
console.log(fn)
//=========
// 函數的聲明優先級高於變量的聲明
// 同名函數會覆蓋函數與變量
// 同名變量不會覆蓋函數

//建立階段,聲明
function fn(){console.log('fn')}
function fn(){console.log('cover fn')}
function a() {console.log('cover a')}
var a = undefined
var fn = undefined

//建立階段,按代碼順序進行賦值和函數的調用
a = 20
console.log(a) // 20
fn() //cover fn
fn = 'I want cover function named fn.'
console.log(fn) //'I want cover function named fn.'
//=========end====

基於函數上下文分析spa

//demo1.js
function test(){
  console.log(a)
  console.log(foo())
  var a = 1
  function foo(){
   return 2
  }
}
test()

//建立過程
testEC = {
  vo:{}//變量對象
  scopeChain:[]//做用域鏈 
  this:{}
}

//就看該函數的執行上下文的VO的建立
Vo = {
  arguments:{...},
  foo:<foo reference>,
  a:undefined
}
//執行階段,活動對象AO,AO還包含了this的指向,全部你在函數中使用箭頭函數的時候,this的指向也是經過這裏肯定
VO=>AO = {
  arguments:{...},
  foo:<foo reference>,
  a:undefined,
  this:window
}

全局上下文的變量對象

 每種語言總有一些普通奇奇怪怪的東西,例如:Java不支持多繼承,恰恰默認繼承Object對象code

windowEC = {
  vo:window,
  scopeChain:{},
  this:window
}
相關文章
相關標籤/搜索