令人驚奇的JavaScript面向?qū)ο?二)
昨天談了作用域的問(wèn)題,現(xiàn)在讓我們看看作用域在JavaScript的面向?qū)ο筇匦灾惺窃趺幢憩F(xiàn)的,其中會(huì)涉及到上下文的問(wèn)題,這個(gè)也是我們需要好好去理解的。
學(xué)習(xí)JavaScript面向特性的朋友可能會(huì)迷惑于JavaScript中所謂類(lèi)聲明的方式。類(lèi)似以下代碼:
function WhatIam() {
alert('I'm here');
}
你可以用它來(lái)聲明一個(gè)變量:
test = new WhatIam();
或者像函數(shù)一樣調(diào)用它:
WhatIam();
這時(shí)候我們完全puzzled了,它究竟是個(gè)什么東西? 我只能說(shuō),它是一個(gè)特殊的又讓人頭痛的東西。但是不要緊,只要我們能看清它是怎樣運(yùn)作的,不怕它是神還是鬼。
可能你在上面的代碼運(yùn)行情況中看不出當(dāng)一個(gè)function用來(lái)聲明變量和作為函數(shù)調(diào)用,它除了返回值之外還有什么不同。但是通過(guò)接下來(lái)的一些例子,相信你會(huì)對(duì)這兩種用法會(huì)有更加深入的理解。
首
先說(shuō)說(shuō)為什么一個(gè)function可以像類(lèi)一樣來(lái)聲明一個(gè)變量?我是這樣理解的:任何function都是一個(gè)構(gòu)造函數(shù),你不需要定義類(lèi),而當(dāng)你聲明
function的時(shí)候,實(shí)際上已經(jīng)在定義一個(gè)類(lèi)了。這樣看來(lái),用function定義出來(lái)的函數(shù)實(shí)際上就是一個(gè)類(lèi)的構(gòu)造函數(shù)了。
=================這里觀摩一種神奇現(xiàn)象===================
關(guān)于這個(gè)構(gòu)造函數(shù)我必須跟大家說(shuō)明一種情況,在上一篇文章中我曾提到,在函數(shù)中聲明的變量,如果不加var關(guān)鍵字,那么它默認(rèn)是一個(gè)全局變量(也即window對(duì)象下的一個(gè)屬性)。然而在這樣的構(gòu)造函數(shù)中,卻存在一種特殊的情況(我至今都沒(méi)搞明白的神奇“失蹤”現(xiàn)象):
function TestClass() {
//你會(huì)發(fā)覺(jué)這是在定義一個(gè)全局變量
val = 1;
alert(val);
//果然它是一個(gè)全局變量
alert(window.val);
};
//調(diào)用TestClass構(gòu)造函數(shù)
test = new TestClass();
//再次驗(yàn)證是一個(gè)全局變量
alert(val);
運(yùn)行結(jié)果并沒(méi)有什么不妥,一切都在意料之中。然而下面這段代碼的運(yùn)行結(jié)果卻絕對(duì)讓你目瞪口呆:
function TestClass() {
//我認(rèn)為我在定義一個(gè)全局變量
val = 1;
//正常顯示1
alert(val);
//居然是undefined!
alert(window.val);
//我僅僅是添加了以下代碼
var val = 10;
//顯示了10,這里比較好理解,就是局部變量作用域遮蓋了全局作用域
alert(val);
//依然是undefined
alert(window.val);
}
//調(diào)用TestClass構(gòu)造函數(shù)
test = new TestClass();
//確實(shí)是undefined
alert(val);
看到這里你是不是已經(jīng)瘋狂了?我也是。最開(kāi)始定義的val全局變量為何神奇失蹤?
對(duì)于這種情況我也只是順帶提一下,希望引起大家注意,但是我并不能解釋為何出現(xiàn)這樣的現(xiàn)象,等待高人注解!!
關(guān)于這個(gè)現(xiàn)象說(shuō)一點(diǎn)我的看法就是:如果你聲明function的目的是定義一個(gè)類(lèi),就要盡量擯棄在其中使用全局變量的做法,這樣就可以避免上述現(xiàn)象的發(fā)生。
posted on 2008-07-23 21:31 Jarod.cn.LuLuLife 閱讀(185) 評(píng)論(0) 編輯 收藏