昨天談了範圍的問題,現在讓我們看看範圍在JavaScript的物件導向特性中是怎麼表現的,其中會涉及到內容相關的問題,這個也是我們需要好好去理解的。
學習JavaScript面向特性的朋友可能會迷惑於JavaScript中所謂類聲明的方式。類似以下代碼:
function WhatIam() {
alert('I'm here');
}
你可以用它來聲明一個變數:
test = new WhatIam();
或者像函數一樣調用它:
WhatIam();
這時候我們完全puzzled了,它究竟是個什麼東西? 我只能說,它是一個特殊的又讓人頭痛的東西。但是不要緊,只要我們能看清它是怎樣運作的,不怕它是神還是鬼。
可能你在上面的代碼運行情況中看不出當一個function用來聲明變數和作為函數調用,它除了傳回值之外還有什麼不同。但是通過接下來的一些例子,相信你會對這兩種用法會有更加深入的理解。
首先說說為什麼一個function可以像類一樣來聲明一個變數?我是這樣理解的:任何function都是一個建構函式,你不需要定義類,而當你聲明function的時候,實際上已經在定義一個類了。這樣看來,用function定義出來的函數實際上就是一個類的建構函式了。
=================這裡觀摩一種神奇現象=================== (請參照評論,現在已經轉變為正常現象了呵呵)
關於這個建構函式我必須跟大家說明一種情況,在上一篇文章中我曾提到,在函數中聲明的變數,如果不加var關鍵字,那麼它預設是一個全域變數(也即window對象下的一個屬性)。然而在這樣的建構函式中,卻存在一種特殊的情況(我至今都沒搞明白的神奇“失蹤”現象):
function TestClass() {
//你會發覺這是在定義一個全域變數
val = 1;
alert(val);
//果然它是一個全域變數
alert(window.val);
};
//調用TestClass建構函式
test = new TestClass();
//再次驗證是一個全域變數
alert(val);
運行結果並沒有什麼不妥,一切都在意料之中。然而下面這段代碼的運行結果卻絕對讓你目瞪口呆:
function TestClass() {
//我認為我在定義一個全域變數
val = 1;
//正常顯示1
alert(val);
//居然是undefined!
alert(window.val);
//我僅僅是添加了以下代碼
var val = 10;
//顯示了10,這裡比較好理解,就是局部變數範圍遮蓋了全域範圍
alert(val);
//依然是undefined
alert(window.val);
}
//調用TestClass建構函式
test = new TestClass();
//確實是undefined
alert(val);
看到這裡你是不是已經瘋狂了?我也是。最開始定義的val全域變數為何神奇失蹤?
對於這種情況我也只是順帶提一下,希望引起大家注意,但是我並不能解釋為何出現這樣的現象,等待高人註解!!
關於這個現象說一點我的看法就是:如果你聲明function的目的是定義一個類,就要盡量擯棄在其中使用全域變數的做法,這樣就可以避免上述現象的發生。
==================神奇現象到此結束==================== “神奇現象”解釋經大牛指點已經明晰,有興趣可以參照評論
撇開那神奇現象,接下來讓我們真正進入JavaScript的物件導向世界~
但是現在餓了,等我吃過午飯再繼續呵呵~