JS物件導向編程淺析

來源:互聯網
上載者:User

在AJAX興起以前,很多人寫JS可以說都是毫無章法可言的,基本上是想到什麼就寫什麼,就是一個接一個的函數function,遇到重複的還得copy,如果一不小心函數重名了,還真不知道從何開始尋找錯誤,因為大家總是用面向過程的編程思想來寫JS代碼,而且也由於網路上充斥了太多小“巧”的JS程式碼片段,很多都是隨意而為,很不規範,這也就造成了大家對JS的“誤解”,一味的認為它就是一個輔助的小東東,而不適合做大的東西開發。但是自從AJAX興起後,大量的JS代碼編寫要求人們具備像寫JAVA類似的代碼一樣,能夠物件導向進行開發。

所以下面就結合我自己的體會和所學習的東東和大家一起來學習在JS中如何使用物件導向的編程。其實使用JS進行物件導向開發也不是很難的事情,因為在JS中每一個function就是一個對象,比如如下一個函數:
複製代碼 代碼如下:
function HelloWorld()
{
alert('hello world!');
}

那麼我們在使用的時候就可以把它當成一個對象來使用,比如使用如下的測試函數:
複製代碼 代碼如下:
function _test()
{
var obj = new HelloWorld();
}

那麼在調用_test方法後就會彈出hello world!的提示框,也就是調用了HelloWorld()對象(函數)。在這裡HelloWorld這個對象沒有任何屬性和方法,它只有一個構造方法HelloWorld(),我們可以把它想象成JAVA中的一個沒有任何屬性和方法的類,當使用new進行對象建立的時候,就調用了它的構造方法。這也是我們最簡單的對象了,當然了,一個對象肯定是要賦予它屬性和方法的,在JS中我們使用prototype原型關鍵字進行賦值,比如我要給HelloWorld對象增加一個sayHello方法和一個name屬性,那麼就可以這樣添加:
複製代碼 代碼如下:
HelloWorld.prototype = {
name : 'JavaScript',
sayHello : function() {
alert(this.name);
}
}

那麼就可以為HelloWorld添加了一個name屬性和sayHello方法,我們再改一下_test方法,如下:
複製代碼 代碼如下:
function _test()
{
var obj = new HelloWorld();
obj.sayHello();
}

那麼調用_test方法後就會先後列印hello wordl!和JavaScript(一個是構造方法中的alert,一個是sayHello方法中的alert)。注意sayHello方法中的alert引用了this關鍵字,該關鍵字表示的就是HelloWorld對象,即預設指向該對象,和JAVA中的this關鍵字一樣。

對於向一個對象添加執行個體方法和屬性,我們可以採用上述的方式,即使用prototype關鍵字進行賦值,格式如下:
複製代碼 代碼如下:
對象名稱.prototype = {
屬性一 : 屬性值,
屬性二 : 屬性值,
方法一 : function(參數列表) {
方法體;
},
方法二 : function(參數列表) {
方法體;
}
}

可以按照如上方式對一個對象進行多個屬性和方法的定義,這樣在new一個對象後,就可以使用執行個體名稱.屬性或方法來擷取屬性或執行方法了。

在上面的方法中,大家不知道發現沒有對象的屬性是可以直接存取的,比如訪問HelloWorld對象的name屬性就可以使用obj.name直接擷取。這就好比我們JAVA中的公有屬性了,而且我們還可以直接對name屬性進行賦值操作。所以現在有一個問題了,我們如何給一個對象賦一個私人成員變數呢?那我們就可能要改一下HelloWorld類的聲明方式了,不使用prototype進行類的屬性和方法聲明,而是直接使用內嵌函數和屬性進行聲明,修改的HelloWorld如下,我們命名為HelloWorld2:
複製代碼 代碼如下:
function HelloWorld2()
{
var privateProp = 'hello world 2!';
this.method = function() {
alert(privateProp);
}
}

看到HelloWorld2的類申明方式了沒?是直接在函數內部進行了函數嵌套申明,而且我們還設定了一個局部變數privateProp,即我們的私人成員變數,該變數只能被HelloWorld2內部的函數進行訪問,外部存取是不允許的,這樣我們就可以通過使用變數的範圍來巧妙的設定類的私人變數了。我們應用如下:
複製代碼 代碼如下:
function _test2()
{
var obj2 = new HelloWorld2();
obj2.method(); // 調用該方法將列印'hello world 2!
alert(obj2.privateProp); // 將列印undefined
}

上面所說的都是如何定義一個類,以為如何為一個類定義屬性和方法,由於採用prototype方式進行定義清晰明了,所以一般都是使用該方式進行類的定義,而且現在很多AJAX架構中都使用了類似的類聲明方式。而且類的私人成員變數卻只能在類的構造方式中的函數進行訪問,這樣類的prototype聲明的方法就不能訪問該私人成員變數了,而且可讀性方面也沒有prototype方式好。

好了,上面所說的都是定義一個類的執行個體方法和屬性。在JAVA中類有執行個體方法和屬性與類方法和屬性之分。所謂類屬性和方法就是該類的所有執行個體都只維護一份類屬性和類方法的副本,而不是每個執行個體都維護一套,這和執行個體屬性和執行個體方法是不一樣的。那麼在JS中如何為一個類定義靜態類方法和類屬性呢?我們可以直接為類添加靜態屬性和靜態方法,比如為HelloWorld類添加一個age的靜態屬性和一個hello的靜態方法,那麼聲明如下:
複製代碼 代碼如下:
HelloWorld.age = 22;
HelloWorld.hello = function() {
alert(HelloWorld.age);
}

那麼這樣就為類HelloWorld聲明了靜態屬性age和靜態方法hello了。在使用的時候就直接使用類名進行訪問了,但是不能使用執行個體進行訪問,這點與JAVA中的是一致的,測試如下:
複製代碼 代碼如下:
function _test()
{
var obj = new HelloWorld();
obj.sayHello(); // 正確,執行個體方法,可以通過執行個體進行訪問
HelloWorld.hello(); // 正確,靜態方法,通過類名進行直接存取
obj.hello(); // 錯誤,不能通過執行個體訪問靜態方法。會報JS錯誤!
}

通過以上的說明,相信大家對JS進行物件導向編程有了一定的瞭解,而且也一定蠢蠢欲動了吧,呵呵,大家不妨試試(提示:以上代碼全部通過測試!)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.