在JavaScript中萬物皆對(duì)象跳纳,面向?qū)ο缶幊虒?duì)象抽象成類 通過類來創(chuàng)建對(duì)象 與面向過程相比 大大提高了程序的可維護(hù)性 可擴(kuò)展性 簡單來說就是 以類的方式組織代碼 以對(duì)象的方式組織數(shù)據(jù) 窃植。但是又不能說是一個(gè)真正意義上的面向?qū)ο螅╫op)語言,因?yàn)樗鼪]有類(class),雖然說在ES6中有關(guān)鍵字class,但這只是對(duì)構(gòu)造函數(shù)做的一個(gè)封裝而已赴背;那么在ES5中旋奢,我們想要模擬一個(gè)類的話,把屬性和方法放到一個(gè)對(duì)象里面湃缎,這個(gè)組合的過程就叫做封裝岁忘。我們用一句話概括就是:?把客觀事物封裝成抽象的類,隱藏屬性和方法的實(shí)現(xiàn)細(xì)節(jié)深员,僅對(duì)外公開接口 负蠕。?
一、普通生成實(shí)例對(duì)象
? ? 我們假設(shè)為一個(gè)用戶a創(chuàng)建一個(gè)對(duì)象倦畅,對(duì)象里面有name和age兩個(gè)屬性:
? ? ? ?var a = {
? ? ? ? ? ? name: "張三"遮糖,? ? ? ? ? ? age: 23
????????}
? ? 接著我們依據(jù)這個(gè)對(duì)象的模式,為第二個(gè)用戶b也生成一條數(shù)據(jù):
????var b = {
????????name: "李四"叠赐,
????????age: 25
? }
這個(gè)就是最普通的封裝了欲账,很明顯的看出了它的缺點(diǎn):
1、當(dāng)我們要?jiǎng)?chuàng)建多個(gè)用戶的話還必須這樣創(chuàng)建多個(gè)對(duì)象芭概,代碼重復(fù)太麻煩了赛不;
?2、兩個(gè)對(duì)象之間并沒有發(fā)現(xiàn)它們之間有什么樣的關(guān)聯(lián)罢洲;
二踢故、改進(jìn)
依照上面的方法我們可以用一個(gè)公用的方法,來避免代碼過多的問題:
function create(name, age) {
????return {
? ? ? ? name: name,
? ? ? ? age: age
????}}
var a =? create('張三',? 23)
var b = create('李四'惹苗,25)
這種方法解決了上個(gè)方法重復(fù)代碼的問題的問題畴椰,缺依舊沒有看到a和b之間沒有內(nèi)在的聯(lián)系,不能反映出它們是同一個(gè)原型對(duì)象的實(shí)例鸽粉。
三斜脂、使用構(gòu)造函數(shù):
創(chuàng)建對(duì)象的方式包括兩種:對(duì)象字面量和使用new表達(dá)式,我們上面的方法都是使用對(duì)象字面量的方法触机,發(fā)現(xiàn)并不能滿足我們預(yù)期的效果帚戳;new表達(dá)式是配合構(gòu)造函數(shù)使用的,所謂"構(gòu)造函數(shù)"儡首,內(nèi)部使用了this變量片任。對(duì)構(gòu)造函數(shù)使用new運(yùn)算符,就能生成實(shí)例蔬胯,并且this變量會(huì)綁定在實(shí)例對(duì)象上对供。簡單來說,構(gòu)造函數(shù)就是你用new關(guān)鍵字創(chuàng)建對(duì)象時(shí)調(diào)用的函數(shù)。
以上的原型可以這樣寫:
????function create(name,age){
this.name=name;
this.age=age;
}
依據(jù)原型我們生成實(shí)例:
var a =? new create('張三',? 23)
var b =? new create('李四', 25)
我們不僅能夠使代碼更加簡潔产场,還能夠看出實(shí)例對(duì)象與原型對(duì)象之間的關(guān)系鹅髓,我們可以通過實(shí)例對(duì)象的constructor屬性來判斷生成它的構(gòu)造函數(shù)對(duì)象:
console.log(a.constructor === b.constructor)? //true
三、構(gòu)造函數(shù)的優(yōu)化:
雖然構(gòu)造函數(shù)能夠很好的實(shí)現(xiàn)封裝京景,但是它本身也存在的問題點(diǎn)就是現(xiàn)在構(gòu)造函數(shù)里面的屬性都是根據(jù)實(shí)例傳過來的參數(shù)來動(dòng)態(tài)確定的窿冯,那么我們想在這個(gè)對(duì)象里面定義一個(gè)變的屬性,比如:
????function create(name,age){
this.name=name;
this.age=age;
? ? ? ? ? ? ? ?this.address = '廈門'
}
這樣導(dǎo)致每生成一個(gè)實(shí)例的話都要去定義一個(gè)相同的內(nèi)容确徙,導(dǎo)致浪費(fèi)的內(nèi)存醒串,這個(gè)時(shí)候我們可以運(yùn)用到上一節(jié)說到的原型鏈的概念:把不變的屬性和方法放到構(gòu)造函數(shù)的prototype屬性指向的對(duì)象里面,生成的實(shí)例都能夠得到繼承鄙皇。在下一章也將詳細(xì)的分享面向?qū)ο蟮睦^承芜赌。針對(duì)以上代碼優(yōu)化后的結(jié)果如下:
????function create(name,age){
this.name=name;
this.age=age;
}
create.prototype.address = '廈門'
以上是自己作為一位幫運(yùn)工的一個(gè)概括和分享,歡迎大家的指正和批評(píng)伴逸。缠沈。
在下一章我們將來探討面向?qū)ο缶幊痰牡诙€(gè)內(nèi)容 -- 繼承。