面向物件程式設計(一)-- 封裝
在JavaScript中萬物皆物件,面向物件程式設計將物件抽象成類 通過類來建立物件 與面向過程相比 大大提高了程式的可維護性 可擴充套件性 簡單來說就是 以類的方式組織程式碼 以物件的方式組織資料 。但是又不能說是一個真正意義上的面向物件(oop)語言,因為它沒有類(class),雖然說在ES6中有關鍵字class,但這只是對建構函式做的一個封裝而已;那麼在ES5中,我們想要模擬一個類的話,把屬性和方法放到一個物件裡面,這個組合的過程就叫做封裝。我們用一句話概括就是:把客觀事物封裝成抽象的類,隱藏屬性和方法的實現細節,僅對外公開介面 。
一、普通生成例項物件
我們假設為一個使用者a建立一個物件,物件裡面有name和age兩個屬性: var a = { name: "張三", age: 23 }
接著我們依據這個物件的模式,為第二個使用者b也生成一條資料:
var b = { name: "李四", age: 25 }
這個就是最普通的封裝了,很明顯的看出了它的缺點:
1、當我們要建立多個使用者的話還必須這樣建立多個物件,程式碼重複太麻煩了;
2、兩個物件之間並沒有發現它們之間有什麼樣的關聯;
二、改進
依照上面的方法我們可以用一個公用的方法,來避免程式碼過多的問題:
function create(name, age) { return { name: name, age: age } } var a = create('張三', 23) var b = create('李四',25)
這種方法解決了上個方法重複程式碼的問題的問題,缺依舊沒有看到a和b之間沒有內在的聯絡,不能反映出它們是同一個原型物件的例項。
三、使用建構函式:
建立物件的方式包括兩種:物件字面量和使用new表示式,我們上面的方法都是使用物件字面量的方法,發現並不能滿足我們預期的效果;new表示式是配合建構函式使用的,所謂"建構函式",內部使用了this變數 。對建構函式使用new運算子,就能生成例項,並且this變數會繫結在例項物件上。簡單來說,建構函式就是你用new關鍵字建立物件時呼叫的函式。
以上的原型可以這樣寫:
function create(name,age){ this.name=name; this.age=age; }
依據原型我們生成例項:
var a = new create('張三', 23) var b = new create('李四', 25)
我們不僅能夠使程式碼更加簡潔,還能夠看出例項物件與原型物件之間的關係,我們可以通過例項物件的constructor屬性來判斷生成它的建構函式物件:
console.log(a.constructor === b.constructor) //true
三、建構函式的優化:
雖然建構函式能夠很好的實現封裝,但是它本身也存在的問題點就是現在建構函式裡面的屬性都是根據例項傳過來的引數來動態確定的,那麼我們想在這個物件裡面定義一個變的屬性,比如:
function create(name,age){ this.name=name; this.age=age; this.address = '廈門' }
這樣導致每生成一個例項的話都要去定義一個相同的內容,導致浪費的記憶體,這個時候我們可以運用到上一節說到的原型鏈的概念:把不變的屬性和方法放到建構函式的prototype屬性指向的物件裡面,生成的例項都能夠得到繼承。在下一章也將詳細的分享面向物件的繼承。針對以上程式碼優化後的結果如下:
function create(name,age){ this.name=name; this.age=age; } create.prototype.address = '廈門'
以上是自己作為一位幫運工的一個概括和分享,歡迎大家的指正和批評。。
在下一章我們將來探討面向物件程式設計的第二個內容 -- 繼承。