深入學(xué)習(xí)js之——變量對象#4

開篇

上一篇文章重點介紹的是執(zhí)行山下文棧,當(dāng)javascript代碼執(zhí)行一段可執(zhí)行的代碼(executable code)時候,會創(chuàng)建對應(yīng)的執(zhí)行上下文(execution context)。

對于每一個執(zhí)行上下文,都有三個重要的屬性:

  • 變量對象(Variable object VO)
  • 作用域鏈(Scope chain)
  • this

本文重點介紹創(chuàng)建變量對象的過程。

變量對象

變量對象是與執(zhí)行上下文相關(guān)的數(shù)據(jù)作用域,存儲了再上下文中定義的變量和函數(shù)聲明。

因為不同執(zhí)行山下文下的變量對象稍有不同,所以我們來聊聊全局上下文下的變量對象和函數(shù)上下文下的變量對象。

全局上下文

我們先了解一個概念,叫做全局對象。在W3CSchool中也有介紹:

全局對象是預(yù)定義的對象,作為 JavaScript 的全局函數(shù)和全局屬性的占位符。通過使用全局對象,可以訪問所有其他所有預(yù)定義的對象、函數(shù)和屬性。

在頂層 JavaScript 代碼中,可以用關(guān)鍵字 this 引用全局對象。因為全局對象是作用域鏈的頭,這意味著所有非限定性的變量和函數(shù)名都會作為該對象的屬性來查詢。

例如,當(dāng)JavaScript 代碼引用 parseInt() 函數(shù)時,它引用的是全局對象的 parseInt 屬性。全局對象是作用域鏈的頭,還意味著在頂層 JavaScript 代碼中聲明的所有變量都將成為全局對象的屬性。

如果感覺全局對象有些看不懂的話,容我再來介紹一下全局對象:

1.可以通過this引用,在客戶端javascript中,全局對象就是window對象。

console.log(this); // window

2.全局對象是由Object 構(gòu)造函數(shù)實例化的一個對象。

console.log(this instanceof Object); // true

3.預(yù)定義一堆,恩,一大堆的函數(shù)和屬性。

// /都能生效
console.log(Math.random());
console.log(this.Math.random());

4.作為全局變量的宿主。

var a = 1;
console.log(this.a);

5.客戶端javascript中,全局對象window屬性指向自身

var a = 1;
console.log(window.a);

this.window.b = 2;
console.log(this.b);

花了一個大篇幅介紹全局對象,其實就是想說:

全局上下文中的變量對象就是全局對象吶!

函數(shù)執(zhí)行上下文

在函數(shù)上下文中,我們用活動對象(activation object,AO)

活動對象和變量對象其實是一個東西,只是變量對象是規(guī)范上的或者是引擎實現(xiàn)的,不可在javascript環(huán)境中訪問,只有進入一個執(zhí)行上下文中,這個執(zhí)行上下文的變量對象才會被激活,所以才叫做 activation object,而只有被激活的變量對象,也就是活動對象上的各種屬性才能被訪問。

活動對象是在進入函數(shù)上下文時刻被創(chuàng)建的,它通過函數(shù)的arguments屬性初始化,arguments屬性值是Arguments對象。

執(zhí)行過程

執(zhí)行上下文的代碼會分成兩個階段進行處理:分析和執(zhí)行,我們也可以叫做:
1、進入執(zhí)行山下文
2、代碼執(zhí)行

進入執(zhí)行上下文

進入執(zhí)行上下文的時候,這個時候還沒有執(zhí)行代碼,

變量對象包括:
1、函數(shù)的所有形參(如何是函數(shù)上下文)

* 由名稱和對應(yīng)的值組成一個變量對象的屬性被創(chuàng)建
* 沒有實參,屬性值設(shè)置為 undefined

2、函數(shù)聲明

* 由名稱和對應(yīng)值(函數(shù)對象(function-object))組成一個變量對象的屬性被創(chuàng)建
* 如果變量對象已經(jīng)存在相同名稱的屬性,則完全替換這個屬性

3、變量聲明

* 由名稱和對應(yīng)值(undefined)組成一個變量對象的屬性被創(chuàng)建;
* 如果變量名稱跟已經(jīng)聲明的形式參數(shù)或函數(shù)相同,則變量聲明不會干擾已經(jīng)存在的這類屬性

舉個例子:

  function foo(a) {
    var b = 2;
    function c() {}
    var d = function() {};
    b = 3;
  }
  foo(1);

在進入執(zhí)行上下文后,這時候的 AO 是

  AO = {
    arguments: {
      0: 1,
      length: 1
    },
    a: 1,
    b: undefined,
    c: reference to function c(){},
    d: undefined
  }

代碼執(zhí)行

在代碼執(zhí)行階段,會順序的執(zhí)行代碼,根據(jù)代碼,修改變量對象的值

這是上面的例子,當(dāng)代碼執(zhí)行完后,這時的AO是:

AO = {
  arguments: {
    0: 1,
    length: 1
  },
  a: 1,
  b: 3,
  c: reference to function c(){},
  d: reference to FunctionExpression "d"
}

到這里變量對象的創(chuàng)建過程就介紹完了,讓我們簡潔的總結(jié)我們上述所說:

  1. 全局上下文的變量對象初始化是全局對象
  2. 函數(shù)上下文的變量對象初始化只包括 Arguments 對象
  3. 在進入執(zhí)行上下文時會給變量對象添加形參、函數(shù)聲明、變量聲明等初始的屬性值
  4. 在代碼執(zhí)行階段,會再次修改變量對象的屬性值

思考題

最后我們看幾個例子:

第一題:

 function foo(){
   console.log(a);
   a = 1;
 }

 foo(); // ??

 function bar(){
  a = 1;
  console.log(a);
 }

 bar(); // ??

第一段會報錯:Uncaught ReferenceError: a is not defined。
第二段會打?。?code>1。

這是因為函數(shù)中的 "a" 并沒有通過 var 關(guān)鍵字聲明,所有不會被存放在 AO 中。

第一段執(zhí)行 console 的時候, AO 的值是:

AO = {
    arguments: {
        length: 0
    }
}

沒有 a 的值,然后就會到全局去找,全局也沒有,所以會報錯。

當(dāng)?shù)诙螆?zhí)行 console 的時候,全局對象已經(jīng)被賦予了 a 屬性,這時候就可以從全局找到 a 的值,所以會打印 1。

第二題:

console.log(foo);

function foo(){
  console.log("foo");
}

var foo = 1;

會打印函數(shù),而不是 undefined 。

這是因為在進入執(zhí)行上下文時,首先會處理函數(shù)聲明,其次會處理變量聲明,如果如果變量名稱跟已經(jīng)聲明的形式參數(shù)或函數(shù)相同,則變量聲明不會干擾已經(jīng)存在的這類屬性。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概要 64學(xué)時 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,874評論 0 3
  • 一切皆對象 js中的一個常見運算符 typeof 以上代碼列出了 typeof 輸出的集中類型標(biāo)識, 其中上面的四...
    無跡落花閱讀 2,093評論 0 5
  • 函數(shù)和對象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句,而且...
    道無虛閱讀 4,957評論 0 5
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,674評論 1 32
  • 曾經(jīng)意外,他和她相愛。 很多人都說:“曾經(jīng)沒遇見對的人”。其實吧!每個人都是對的,只是每個人都覺得自己青春美麗,帥...
    稻子的平凡生活閱讀 314評論 0 0

友情鏈接更多精彩內(nèi)容