JavaScript變量對象

JavaScript變量對象javascript

  1. 每個執行上下文,都有三個重要的屬性
    • 變量對象
    • 做用域鏈
    • this
變量對象
  1. 變量對象是與執行上下文相關的數據做用域,存儲了在執行上下文中定義的變量和函數聲明
  2. 不一樣執行上下文的變量對象稍有不一樣
 
全局上下文
  1. 全局對象
    • 全局對象是預約義的對象,做爲JavaScript的全局函數和全局屬性的佔位符。經過做用全局對象,能夠訪問全部其餘預約義的對象,函數和屬性。
    • 在頂層JavaScript代碼中,可使用this關鍵詞來引用全局對象。由於全局對象是做用域鏈的頭,這意味着全部非限定性的變量和函數名都會做爲該對象的屬性來查詢。
    • 例如,當JavaScript代碼引用 parselnt()函數時,他引用的是全局對象的 parselnt 屬性。全局對象是做用域鏈的頭,還意味着在頂部JavaScript代碼中聲明的全部變量都將成爲全局對象的屬性。
  2. 能夠經過this引用,在客戶端JavaScript中,全局對象就是Window對象。
    console.log (this)

     

  3. 全局對象是有Object構造函數實例化的一個對象。java

    console.log (this instanceof Object)

     

  4. 預約義了一堆函數和屬性
    console.log (this.Math.random())
    console.log (Math.random())

     

  5. 做爲全局對象的宿主
    var nub = 1
    console.log (this.nub)

     

  6. 客戶端JavaScript中,全局對象window屬性指向自身
    var nub = 1 
    ​​console.log (window.nub)
    ​​​​​​​this.window.b =2
    
    console.log (this.b)

     

函數上下文
  1. 在函數上下文中,咱們用活動對象來表示變量對象
  2. 活動對象和變量對象實際上是一個東西,只是變量對象是規範上的或者說是引擎實現上的,不可在JavaScript環境中訪問,只有當進入一個執行上下文中,這個執行上下文的變量對象纔會被激活,而只有被激活的變量對象,也就是活動對象上的各類屬性才能被訪問。
  3. 活動對象是在進入函數上下文時被建立的,他經過函數的 arguments屬性初始化。arguments屬性值是Arguments 對象。
執行過程
  1. 執行上下文的代碼會分紅兩個階段進行處理:分析和執行,咱們也能夠叫作:
    1. 進入執行上下文
    2. 代碼執行
進入執行上下文
  1. 當進入執行上下文的時候,這時候代碼尚未執行
  2. 變量對象包括
      1. 函數的全部行參(若是是函數上下文)
        • 由名稱和對應值組成的一個變量對象的屬性被建立
        • 沒有實參,屬性值設爲 undefined
      2. 函數聲明
        • 由名稱和對應值(函數對象(function-object))組成一個變量對象的屬性被建立
        • 若是變量對象已經存在相同名稱的屬性,則徹底替換這個屬性
      3. 變量聲明
        • 由名稱和對應值(undefined)組成一個變量對象的屬性被建立
        • 若是變量名稱跟已經聲明的形式參數或者函數相同,則變量聲明不會干擾已經存在的這類屬性
  3. 舉個例子:
function foo(a){
 var b = 2
 function c(){}
 var d = function (){}
 b = 3
}
foo(1)

在進入執行上下文後,這時候的AO是:
AO = {
 arguments:{
  0:1 ,
  length:1
 },
 a:1,
 b:undefined,
 c:function (){},
 d:undefined
}

代碼執行
在代碼執行階段,會順序執行代碼,根據代碼,修改變量對象的值
當代碼執行完畢,這時候的AO是:
AO = {
 arguments:{
  0:1 ,
  length:1
 },
 a:1,
 b:3,
 c:function (){},
 d:reference to FunctionExpression "d"
}

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

思考題:dom

  1. 第一題:
function foo(){
 console.log(a)
 a = 1
}
foo()// a is not defined

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

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

這是由於函數中的a並無經過 var 關鍵字聲明,因此不會被放在AO中。
第一段執行console的時候,AO的值爲:
AO = {
 arguments: {
  length:0
 }
}
沒有a的值,就會到全局中去尋找,全局也沒有,因此會報錯
當第二段執行console的時候,全局對象已經被賦予了a屬性,這時候全局就能找到a的值,因此會打印1

第二題:函數

console.log(foo)// [Function: foo]

function foo(){
 console.log('foo')
}
var foo = 1
console.log(foo)// 1

首先會打印函數 而不是undefined。
這是由於在進入執行上下文時,首頁會處理函數聲明,其次會處理變量聲明,若是變量名稱跟已經聲明的形參或者函數相同,則變量聲明不會干擾已經存在的這類屬性。
相關文章
相關標籤/搜索