本來打算去睡覺了,再開啟blog一看,發現深夜了還有貴客來訪。為感謝 真 OO無雙 的關注,決定寫完這篇再去睡覺~ 有什麼錯漏或者值得討論的地方請大家不吝指出!
ok,其實昨天就打算寫這一部分內容了,但是被那個所謂的“神奇現象”打亂了陣腳,看了MS的JScript文檔之後才發覺是個笑話。不過不管怎麼說,還是學到了東西呵呵,感謝昨天所有在此留言賜教的朋友呵呵~
接下來我為大家介紹一下JavaScript中的一些重要的物件導向特性或者基本的概念。(注意,我說的是物件導向“特性”,我並沒有認為JavaScript是一門物件導向語言,但是它確確實實有物件導向語言方面的一些特性,這是值得我們利用的。)
1.成員變數。照例先看一段代碼
1 function TestClass()
2 {
3 //“私人”成員變數
4 var val = 1;
5 //“公有”成員變數
6 this.val = 10;
7
8 //驗證
9 alert(val);
10 alert(this.val);
11 };
12
13 //聲明一個對象
14 var test = new TestClass();
15 //只能訪問到公有成員
16 alert(test.val);
ok, 現在讓我們看看什麼是“公有”什麼是“私人”。雖然大牛大蝦們可能會不屑一顧,但是仍然寫出來給大家提個醒,畢竟JavaScript這種定義類的方式有時候會讓人摸不著頭腦。
我原來的理解是這樣的:如果用這個function來聲明一個對象,這時候第4行val變數定義的上下文為建構函式內部,實際上是一個局部變數(大家看到這裡先保留一下,後面大家會有其他認識)。而第6行聲明的val上下文是對象內部,所以我們可以把它看成是成員變數。建構函式的最後兩個alert驗證了兩個變數是屬於不同內容相關的變數。第16行的alert像我們展示了this.val這種形式聲明的是一個公有的變數,因為我們可以通過對象從外部直接存取到它。至於為什麼還有“私人”變數一說,請大家移步看下一個例子,第4行val的聲明不僅僅是“局部變數”這麼簡單。
另外再嘮叨一下,雖然和本文沒多大關係:如果把function當成函數調用的話,第6行的上下文就是window對象,也即聲明的是一個全域變數。
2.成員函數。只要理解了上述“公有”變數的定義方法,定義成員函數也成了順理成章的事情。
1 function TestClass()
2 {
3 //“私人”成員變數
4 var val = 1;
5 //“公有”成員變數
6 this.val = 10;
7
8 //定義兩個成員函數
9 this.getPrivateVal = function() {
10 //返回“私人”變數
11 return val;
12 }
13 this.getPublicVal = function() {
14 //返回“公有”變數
15 return this.val;
16 }
17 };
18
19 //聲明一個對象
20 test = new TestClass();
21 //兩種變數都可以通過函數擷取
22 alert(test.getPrivateVal());
23 alert(test.getPublicVal());
你可以看到,實際上所謂的“成員函數”其實就是上一點講到的“公有”變數,僅僅是因為其類型是“function”而已。不過這一點可是需要牢記的東西,記住了才不會在書寫JS代碼的時候還用Java或者C++的風格去定義一個成員函數。
至於上一點中提到的“私人”變數的問題,可以看看getPrivateVal函數的定義以及其調用啟動並執行結果。是不是很神奇?建構函式中的局部變數居然可以在建構函式之外“存活”? 又一個等待大牛大蝦解決的問題呵呵~ 希望很快就能得到回覆!
Anyway,我們可以把它當成“私人”變數使用。
ok,另外還有一種大家熟知的定義“可繼承”函數的方法
function TestClass()
{
//“私人”成員變數
var val = 1;
//“公有”成員變數
this.val = 10;
};
//定義一種可供“繼承”的方法
TestClass.prototype.getVal = function() {
return this.val;
}
//聲明一個對象
test = new TestClass();
alert(test.getVal());
通過原型對象定義的方法。當然,這也是一種“公有”的方法。這樣的定義方法更加受到歡迎。
在《精通JavaScript》一書中,把前一種方法稱為“特權方法”,後一種方法才叫做“公有方法”。這兩種方式定義的方法主要有兩方面的差異,一個是繼承特性,另一個是對建構函式中聲明的變數(之前提到“私人”變數)訪問的許可權。