令人驚奇的JavaScript面向對象(二)
昨天談了作用域的問題,現在讓我們看看作用域在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的目的是定義一個類,就要盡量擯棄在其中使用全局變量的做法,這樣就可以避免上述現象的發生。
posted on 2008-07-23 21:31 Jarod.cn.LuLuLife 閱讀(184) 評論(0) 編輯 收藏