JavaScript設計模式:一、物件導向編程

來源:互聯網
上載者:User

標籤:prot   nbsp   時間   模組   優勢   turn   利用   對象   oop   

JavaScript物件導向編程

  眾所周知,JS作為一門指令碼語言,由於其設計者在設計JS的時候,也僅僅用了很少的時間就完成了JS這門語言的建立,JS雖然擁有著指令碼語言的優勢,但是JS也存在著天生的缺陷。其中之一就是:“沒有完整的物件導向和自訂類型支援”,這是因為JS本身沒有很好的模組化。但事實上是,很多JS學習者或者使用者的共同點是:他們接觸的第一門程式設計語言大都是C++或者Java這種老牌OOP語言,寫代碼時都是秉持著物件導向的思想,這在學習JS或者使用JS不免會感到有一些難受。

  那麼JS可不可以實現物件導向編程,或者說,在某種程度上做到物件導向編程?答案是肯定的。

一、用對象收編函數與變數

  我們先看三個函數: 

 1 function fn1 () { 2   // ... 3 } 4  5 function fn2 () { 6   // ... 7 } 8  9 function fn3 () {10   // ...11 }

  這段代碼有一個問題就在於:定義了三個全域函數,在一個項目裡,這是不提倡的事實上也是不被允許的,建立全域函數或者變數,意味著在以後的代碼裡,這些函數或者變數就有與他人的代碼產生衝突的可能。那麼怎麼解決這一類的問題呢?

  我們知道,對象可以擁有自己的屬性與方法,並且在我們需要使用這些屬性和方法的時候,通過點文法來使用。可不可以利用對象來收編這些函數或者變數呢?  看下面的代碼:

 1 var obj = { 2   fn1: function () { 3     // ... 4   } 5   fn2: function () { 6     // ... 7   } 8   fn3: function () { 9     // ...10   }11 }

  通過建立一個這樣的對象,我們就可以通過obj.fn1的方式,來調用對應的方法,並且這些方法是存在於obj對象上的。

  我們再看看下面的這種寫法(與上面的寫法其實是一種意思):

 1 var Obj = function () {} 2 Obj.fn1 = function () { 3   // ... 4 } 5 Obj.fn2 = function () { 6   // ... 7 } 8 Obj.fn3 = function () { 9   // ...10 }

上面的方法存在著另外一個問題,當別人需要使用我們的對象方法的時候就有一些麻煩了,因為這個對象並不能被複製一份或者說我們通過 new 關鍵字

var test = new Obj() ,所建立的新對象test,並不擁有fn1,fn2,fn3這些方法。

要想解決這個問題,我們可以這麼寫:

 1 var Obj = function () { 2   return { 3     fn1: function () { 4       // ... 5     } 6     fn2: function () { 7       // ... 8     } 9     fn3:function () {10       // ...11     }12   }13 }

 這樣寫有什麼作用呢?可以看出,每次調用該函數時,都會返回一個新對象,新對象擁有fn1,fn2,fn3這三個方法。這樣,每個人在使用時就互不影響了。

1 var test = Obj()2 test.fn1()

  我們雖然通過返回一個新對象在一定程度上解決了他人使用的問題,但這並不是真正意義上的類的建立方式(相信Java或者C++使用者深有體會),並且我們上面建立的對象test與Obj沒有任何的關係,所以,我們再次換一種寫法:

 1 var Obj = function () { 2   this.fn1 = function () { 3     // ... 4   } 5   this.fn1 = function () { 6     // ... 7   } 8   this.fn1 = function () { 9     // ...10   }11 }

 我們在這個函數內,使用了this關鍵字,像上面這樣的一個對象Obj,我們就可以將其看成一個類了,擁有三個成員函數:fn1,fn2,fn3,既然是一個類,那麼使用的時候就要通過new關鍵字來建立對象了:

1 var test = new Obj()2 test.fn1()

  另一個問題出現了,每一個使用new關鍵字所建立出來的新對象,通擁有屬於自己的一套方法,但事實上,這並不是必要的,這會造成記憶體不必要的消耗。

  怎麼解決這個問題呢?不知道讀者是否還記得JS中的每一個函數,都有一個prototype對象,我們稱之為“原型”,原型上的屬性和方法是new出來的對象所共用的,我們是否可以將公用的函數轉移到prototype上呢?

 1 var Obj = function () {} 2 Obj.prototype.fn1 = function () { 3   // ... 4 } 5 Obj.prototype.fn2 = function () { 6   // ... 7 } 8 Obj.prototype.fn3 = function () { 9   // ...10 }

這樣我們以後通過new關鍵字建立的對象執行個體,所擁有的都是共同的方法,因為他們都要依賴prototype原型依次尋找,找到的方法都是同一個。

以上的這種方式,還有另一個寫法:

 1 var Obj = function () {} 2 Obj.prototype = { 3   fn1: function () { 4     // ... 5   } 6   fn2: function () { 7     // ... 8   } 9   fn3: function () {10     // ...11   }12 }

   需要注意的是,這兩中方式並不能混用,因為如果在後面為對象的原型對象賦值為新對象的時候,它會覆蓋掉之前對prototype對象賦值的寫法。

  

JavaScript設計模式:一、物件導向編程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.