日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript面向对象——深入理解寄生组合继承

發(fā)布時間:2023/12/31 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript面向对象——深入理解寄生组合继承 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

JavaScript面向?qū)ο蟆钊肜斫饧纳M合繼承

之前談到過組合繼承,會有初始化兩次實例方法/屬性的缺點,接下來我們談談為了避免這種缺點的寄生組合繼承

寄生組合繼承:

思路:組合繼承中,構(gòu)造函數(shù)繼承時已經(jīng)繼承了父類中除了通過prototype定義的公有屬性和方法,也就是說我們需要在原型繼承時繼承父類的原型而不執(zhí)行父類的構(gòu)造函數(shù),這樣就避免了組合繼承中的缺點。

思路有了,如何實現(xiàn)?

讓我們從名字入手,寄生組合繼承,組合繼承我們談過了,寄生是什么東西?《JavaScript設(shè)計模式》這本書中說得比較模糊,因此本人閱讀了另一本更專于介紹JavaScript面向?qū)ο蟮臅禞avaScript面向?qū)ο缶幊讨改系?版》,感覺這本書挺好的,推薦一下:


插播:寄生式繼承

思路:在創(chuàng)建對象的函數(shù)中直接吸收其他對象的功能,然后對其進行擴展并返回。

步驟:

1:設(shè)計inheritObject()函數(shù),名稱自定,只是舉例

設(shè)計理念:函數(shù)可以用來接收新對象,并返回一個以該對象為原型的新對象

function inheritObject(o) {function F() {}F.prototype = oreturn new F()}

2:使用對象標識法定義一個普通對象

var twoD = {name: '2D shape',dimensions: 2}

3:使用inheritObject()函數(shù)對twoD進行操作

function triangle(s, h) {var that = inheritObject(twoD)that.name = 'Triangle'that.side = sthat.height = hthat.getArea = function () {return that.side * that.height / 2}return that}

說明:triangle()中使用inheritObject()將twoD克隆進that對象,并對that對象進行了擴展然后返回。(寄生式繼承的思路:在創(chuàng)建對象的函數(shù)中直接吸收其他對象的功能,然后對其進行擴展并返回,在此函數(shù)中實現(xiàn)。)注意:這個that只是個名稱,可以隨便換另一個,沒有跟保留字this那樣的含義。

這種繼承方式下創(chuàng)建對象,使不使用new都可以,因為返回的就是一個對象。

// testvar t = triangle(5, 10)console.log(t.dimensions)var t2 = new triangle(5, 5)console.log(t2.getArea())

結(jié)果:


插播了一下寄生式繼承的實現(xiàn),現(xiàn)在我們重新談談寄生組合繼承....

寄生組合繼承思路回憶:組合繼承中,構(gòu)造函數(shù)繼承時已經(jīng)繼承了父類中除了通過prototype定義的公有屬性和方法,也就是說我們需要在原型繼承時繼承父類的原型而不執(zhí)行父類的構(gòu)造函數(shù),這樣就避免了組合繼承中的缺點。

實現(xiàn)方案:寄生式繼承+組合繼承,代碼中使用到上邊提到的inheritObject()函數(shù)。

function inheritPrototype(subClass, superClass) {// 復制一份父類的原型副本保存在變量中var p = inheritObject(superClass.prototype)// 修正因為重寫子類原型導致子類的constructor屬性被修改p.constructor = subClass// 設(shè)置子類的原型subClass.prototype = p}

解釋:因為我們只需要父類原型對象的一個副本,這個副本通過原型繼承便可以得到,但是直接賦值給子類是會有問題的,因為對父類對象復制得到的對象p中的constructor指向的不是SubClass子類對象,因此寄生式繼承中要修復復制對象p的constructor屬性指向不正確的問題,最后得到的復制對象p賦值給子類的原型,這樣子類的原型就繼承了父類的原型并且沒有執(zhí)行父類的構(gòu)造函數(shù)。

測試例子:

// 定義父類function SuperClass(name) {this.name = namethis.colors = ['red', 'orange', 'yellow']}// 定義父類原型方法SuperClass.prototype.getName = function () {console.log(this.name)}// 定義子類function SubClass(name, time) {// 構(gòu)造函數(shù)式繼承SuperClass.call(this, name)// 子類新增屬性this.time = time}// 寄生式繼承父類原型inheritPrototype(SubClass, SuperClass)// 子類新增原型方法, 不可以寫在寄生式繼承父類原型函數(shù)前SubClass.prototype.getTime = function () {console.log(this.time)}// 創(chuàng)建測試實例var instance1 = new SubClass('JavaScript', '2018-03-18')var instance2 = new SubClass('NodeJs', '2018-03-19')instance1.colors.push('green')console.log(instance1.colors)console.log(instance2.colors)instance1.getName()instance1.getTime()instance2.getName()instance2.getTime()

解釋:多數(shù)跟組合繼承的一樣,除了這點:子類原型被賦予了父類原型的一個引用,這是個對象,也就是引用類型,所以給子類添加原型方法時只可以通過prototype.語法,不可以使用subClass.prototype={xxx:function(){}}這種對象賦值式的寫法,否則父類的原型會被覆蓋。

運行結(jié)果終于來了.....


最后來一張寄生組合繼承的原理圖,理解了的伙伴請忽略,周日愉快,晚安~(2018.03.18)


總結(jié)

以上是生活随笔為你收集整理的JavaScript面向对象——深入理解寄生组合继承的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。