成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

徹底理解Javascript中的變量對象

Shimmer / 3385人閱讀

摘要:活動對象的變化與處理上下文的兩個階段密切相關(guān)。所有變量聲明由名稱和對應(yīng)值組成一個變量對象的屬性被創(chuàng)建如果變量名稱跟已經(jīng)聲明的形式參數(shù)或函數(shù)相同,則變量聲明不會干擾已經(jīng)存在的這類屬性。

1 定義

如果變量與執(zhí)行上下文相關(guān),那變量自己應(yīng)該知道它的數(shù)據(jù)存儲在哪里,并且知道如何訪問。這種機(jī)制稱為變量對象(variable object)。
變量對象(縮寫為VO)是一個與執(zhí)行上下文相關(guān)的特殊對象,它存儲著在上下文中聲明的以下內(nèi)容:

變量 (var, 變量聲明);

函數(shù)聲明 (FunctionDeclaration, 縮寫為FD);

函數(shù)的形參

舉例來說,我們可以用普通的ECMAScript對象來表示一個變量對象:

VO = {};

就像我們所說的, VO就是執(zhí)行上下文的屬性(property):

activeExecutionContext = {
     VO: {
       // 上下文數(shù)據(jù)(var, FD, function arguments)
      }
};
2 全局上下文中的變量對象

全局上下文中的變量對象就是全局對象,所以我們聲明的變量都是全局對象的屬性。

3 函數(shù)上下文中的變量對象

函數(shù)上下文中的變量對象由活動對象(AO)扮演。

活動對象的變化與處理上下文的兩個階段密切相關(guān)。進(jìn)入執(zhí)行上下文和執(zhí)行代碼。

3.1 進(jìn)入執(zhí)行上下文

當(dāng)進(jìn)入執(zhí)行上下文(代碼執(zhí)行之前)時,VO里已經(jīng)包含了下列屬性:

1. 函數(shù)的所有形參(如果我們是在函數(shù)執(zhí)行上下文中)
   由名稱和對應(yīng)值組成的一個變量對象的屬性被創(chuàng)建;沒有傳遞對應(yīng)參數(shù)的話,那么由名稱和undefined值組成的一種變量對象的屬性也將被創(chuàng)建。
2. 所有函數(shù)聲明(FunctionDeclaration, FD)
由名稱和對應(yīng)值(函數(shù)對象(function-object))組成一個變量對象的屬性被創(chuàng)建;如果變量對象已經(jīng)存在相同名稱的屬性,則完全替換這個屬性。
3. 所有變量聲明(var, VariableDeclaration)
   由名稱和對應(yīng)值(undefined)組成一個變量對象的屬性被創(chuàng)建;如果變量名稱跟已經(jīng)聲明的形式參數(shù)或函數(shù)相同,則變量聲明不會干擾已經(jīng)存在的這類屬性。

也就是變量提升和var x = undefined 不會影響形參x的值,之后調(diào)用x指向的還是形參。

注意:進(jìn)入執(zhí)行上下文時,函數(shù)聲明和變量聲明都提前,但是變量聲明的值還都是undefined,而函數(shù)聲明的變量已經(jīng)可以指向函數(shù)。變量聲明的優(yōu)先級最低。
讓我們看一個例子:

function test(a, b) {
  var c = 10;
  function d() {}
  var e = function _e() {};
  (function x() {});
}
  
test(10); // call

當(dāng)進(jìn)入帶有參數(shù)10的test函數(shù)上下文時,AO表現(xiàn)為如下:

AO(test) = {
  a: 10,
  b: undefined,
  c: undefined,
  d: 
  e: undefined
};

注意,AO里并不包含函數(shù)“x”。這是因為“x” 是一個函數(shù)表達(dá)式(FunctionExpression, 縮寫為 FE) 而不是函數(shù)聲明,函數(shù)表達(dá)式不會影響VO。 不管怎樣,函數(shù)“_e” 同樣也是函數(shù)表達(dá)式,但是就像我們下面將看到的那樣,因為它分配給了變量 “e”,所以它可以通過名稱“e”來訪問。

3.2 代碼執(zhí)行

進(jìn)入上下文階段,AO/VO已經(jīng)擁有了屬性(不過,并不是所有的屬性都有值,大部分屬性的值還是系統(tǒng)默認(rèn)的初始值undefined )。
還是前面那個例子, AO/VO在代碼執(zhí)行期間被修改如下:

AO["c"] = 10;
AO["e"] = ;

另一個經(jīng)典例子:

alert(x); // function
  
var x = 10;
alert(x); // 10
  
x = 20;
  
function x() {};
  
alert(x); // 20

為什么第一個alert “x” 的返回值是function,而且它還是在“x” 聲明之前訪問的“x” 的?為什么不是10或20呢?因為,根據(jù)規(guī)范函數(shù)聲明是在當(dāng)進(jìn)入上下文時填入的; 同意周期,在進(jìn)入上下文的時候還有一個變量聲明“x”,那么正如我們在上一個階段所說,變量聲明在順序上跟在函數(shù)聲明和形式參數(shù)聲明之后,而且在這個進(jìn)入上下文階段,變量聲明不會干擾VO中已經(jīng)存在的同名函數(shù)聲明或形式參數(shù)聲明,因此,在進(jìn)入上下文時,VO的結(jié)構(gòu)如下:

VO = {};
  
VO["x"] = 
  
// 找到var x = 10;
// 如果function "x"沒有已經(jīng)聲明的話
// 這時候"x"的值應(yīng)該是undefined
// 但是這個case里變量聲明沒有影響同名的function的值
  
VO["x"] = 
//緊接著,在執(zhí)行代碼階段,VO做如下修改:
VO["x"] = 10;
VO["x"] = 20;

我們可以在第二、三個alert看到這個效果。
在下面的例子里我們可以再次看到,變量是在進(jìn)入上下文階段放入VO中的。(因為,雖然else部分代碼永遠(yuǎn)不會執(zhí)行,但是不管怎樣,變量“b”仍然存在于VO中。)

if (true) {
 var a = 1;
} else {
 var b = 2;
}
  
alert(a); // 1
alert(b); // undefined,不是b沒有聲明,而是b的值是undefined

本文絕大部分內(nèi)容來自: http://dmitrysoshnikov.com/ec...
僅做少許修改

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86610.html

相關(guān)文章

  • 初學(xué)者徹底理解javascript閉包以及this關(guān)鍵字

    摘要:理解了這句話,我們就可以來看閉包了閉包前面說過,函數(shù)可以訪問函數(shù)作用域鏈中的變量,但如果我們想在函數(shù)外訪問函數(shù)內(nèi)卻不行了。 不管是閉包還是this關(guān)鍵字,都是困擾JS初學(xué)者的比較難懂的東西,如果你對它們的認(rèn)識還不足夠清晰,那么現(xiàn)在就一起把它們掌握掉。還是那句話,我們從最基本的開始,建立起一個非常清晰的知識結(jié)構(gòu),好了,開始吧 ? 閉包 當(dāng)然我們今天說的是javascript里的閉包。要學(xué)...

    魏明 評論0 收藏0
  • 徹底理解Javascript中的作用域鏈

    摘要:全局和上下文中的作用域鏈這里不一定很有趣,但必須要提示一下。全局上下文的作用域鏈僅包含全局對象。代碼的上下文與當(dāng)前的調(diào)用上下文擁有同樣的作用域鏈。代碼執(zhí)行時對作用域鏈的影響在中,在代碼執(zhí)行階段有兩個聲明能修改作用域鏈。 1 定義 我們已經(jīng)知道一個執(zhí)行上下文中的數(shù)據(jù)(參數(shù),變量,函數(shù))作為屬性存儲在變量對象中。 也知道變量對象是在每次進(jìn)入上下文是創(chuàng)建并填入初始值,值的更新出現(xiàn)在代碼執(zhí)行階...

    zhunjiee 評論0 收藏0
  • JavaScript之例題中徹底理解this

    摘要:最后重點理解結(jié)論箭頭函數(shù)的,總是指向定義時所在的對象,而不是運(yùn)行時所在的對象。輸出,箭頭函數(shù)不會綁定所以傳入指向無效。原因是,要徹底理解應(yīng)該是建立在已經(jīng)大致理解了中的執(zhí)行上下文,作用域作用域鏈,閉包,變量對象,函數(shù)執(zhí)行過程的基礎(chǔ)上。 本文共 2025 字,看完只需 8 分鐘 概述 前面的文章講解了 JavaScript 中的執(zhí)行上下文,作用域,變量對象,this 的相關(guān)原理,但是我...

    Hwg 評論0 收藏0
  • 面向對象JavaScript

    摘要:是完全的面向?qū)ο笳Z言,它們通過類的形式組織函數(shù)和變量,使之不能脫離對象存在。而在基于原型的面向?qū)ο蠓绞街校瑢ο髣t是依靠構(gòu)造器利用原型構(gòu)造出來的。 JavaScript 函數(shù)式腳本語言特性以及其看似隨意的編寫風(fēng)格,導(dǎo)致長期以來人們對這一門語言的誤解,即認(rèn)為 JavaScript 不是一門面向?qū)ο蟮恼Z言,或者只是部分具備一些面向?qū)ο蟮奶卣?。本文將回歸面向?qū)ο蟊疽猓瑥膶φZ言感悟的角度闡述為什...

    novo 評論0 收藏0
  • javascript對象不完全探索記錄01:this! which?

    溫馨提示:作者的爬坑記錄,對你等大神完全沒有價值,別在我這浪費(fèi)生命 這一切,源于阮大神博文學(xué)習(xí)Javascript閉包(Closure)- 阮一峰中的一道思考題 //問題1: var name = The Window; var object = {   name : My Object,   getNameFunc : function(){     return function(){    ...

    rubyshen 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<