JavaScript變量對象

JavaScript中,當調用一個函數時,就會有相應的一個執行環境被建立。而一個執行環境的生命週期包含兩個時期javascript

執行環境生命週期:

  • 建立階段
    • 這個階段,執行環境會建立變量對象,創建做用域鏈及肯定this的指向
  • 代碼執行階段
    • 開始執行代碼時,會完成變量賦值,函數調用,以及其餘代碼的執行

變量對象(Variable Object)

變量對象的建立,依次經歷瞭如下幾個過程。java

  1. 創建arguments對象。檢查當前上下文中的參數,創建該對象下的屬性與屬性值。瀏覽器

  2. 檢查當前上下文的函數聲明,也就是使用function關鍵字聲明的函數。在變量對象中以函數名創建一個屬性,屬性值爲指向該函數所在內存地址的引用。若是函數名的屬性已經存在,那麼該屬性將會被新的引用所覆蓋。
  3. 檢查當前上下文中的變量聲明,每找到一個變量聲明,就在變量對象中以變量名創建一個屬性,屬性值爲undefined。若是該變量名的屬性已經存在,爲了防止同名的函數被修改成undefined,則會直接跳過,原屬性值不會被修改。

根據這個規則,理解變量提高就變得十分簡單了。在上面的規則中咱們看出,function聲明會比var聲明優先級更高一點。舉個例子:函數

function demo(){
  console.log(a); //undefind   testfn(); //11   var a = 2;   function testfn() {     console.log(11);   } }
demo();

建立過程(EC:execution context)this

demoEC = {spa

  VO: {},// 變量對象 對象

   scopeChain: {},blog

   this: {}生命週期

}ip

VO 爲 Variable Object的縮寫,即變量對象VO

VO= {

  arguments: {...}, //注:在瀏覽器的展現中,函數的參數可能並非放在arguments對象中,這裏爲了方便理解

  testfn: <foo reference>, // 表示foo的地址引用

  a: undefined
}

未進入執行階段以前,變量對象中的屬性都不能訪問!可是進入執行階段以後,變量對象轉變爲了活動對象,裏面的屬性都能被訪問了,而後開始進行執行階段的操做。(PS:這裏能夠看出其實變量對象活動對象實際上是指向同一個,只是處在執行環境不一樣生命週期)

當走到demo();時,進入執行階段

執行階段VO -> AO // Active ObjectAO
AO = {
  arguments: {...},
  foo: <foo reference>,
  a: 1

}

所以,上面的例子demo,執行順序就變成了這樣

function demo() {
  function testfn() {
    console.log(1);
  }
  var a;
  console.log(a);  
  a = 1;
}

demo() ;

function demo2() {
  console.log(box);
  console.log(car);
  var car = "BWM";
  console.log(car);
  var box = function () {
    console.log("box");
  } 
  function car() {

    console.log("carfn");
  }

}
demo2();

建立階段VO

VO = {

  arguments:{...},

  car:<car refrence>, //這裏car不會被後來var car變量所覆蓋,而是直接跳過

  box:undefind

}

當代碼走到demo2();時,VO>AO

AO = {

  argument:{...},

  car:"BWM",

  box:<boxrefrence>

}

所以,demo2的執行順序就變成了這樣

function demo2() {
  function car() {
    console.log("carfn");
  }
  var box;  

  console.log(box); //undefind

  console.log(car); //<car refrence>  

  car = "BWM";

  console.log(car); //"BWM"
  box = function() {

    console.log("box");
  }
}

demo() ;

全局上下文的變量對象

以瀏覽器中爲例,全局對象爲window。
全局上下文有一個特殊的地方,它的變量對象,就是window對象。而這個特殊,在this指向上也一樣適用,this也是指向window。

windowEC = {

  VO:window,

  Scope chain:{},

  this: window

}

除此以外,全局上下文的生命週期,與程序的生命週期一致,只要程序運行不結束,好比關掉瀏覽器窗口,全局上下文就會一直存在。其餘全部的上下文環境,都能直接訪問全局上下文的屬性。

參考連接:http://mp.weixin.qq.com/s/a_oWYwK0eI_74bMVoGLwCA

相關文章
相關標籤/搜索