JS中的繼承(下)

在上一篇 JS中的繼承(上) 咱們介紹了3種比較經常使用的js繼承方法,若是你沒看過,那麼建議你先看一下,由於接下來要寫的內容, 是創建在此基礎上的.另外本文做爲我我的的讀書筆記,才疏學淺,若有錯誤,敬請指正.前端

接下來咱們要介紹另外3種相對比較奇葩的繼承git

一. 原型式繼承github

function clone (proto) {
    function F () {}
    F.prototype = proto
    return new F()
}
複製代碼

clone 內部首先是建立了一個空的構造函數F,而後把F的prototype指向參數proto,最後返回一個F的實例對象,完成繼承. 原型式繼承看起來跟原型繼承很像,事實上,二者由於都是基於prototype繼承的,因此也有一些相同的特性,好比引用屬性共享問題, 那原型式繼承原型繼承有什麼區別呢? 一個比較明顯的區別就是clone函數接收的參數不必定要是構造函數,也能夠是其餘任何對象, 這樣咱們就至關因而淺複製了一個對象.函數

es5的Object.create()函數,就是基於原型式繼承的this

原型式繼承是道格拉斯-克羅克福德 2006 年在 Prototypal Inheritance in JavaScript一文中提出的es5

二. 寄生式繼承spa

寄生式繼承其實就是在原型式繼承的基礎上,作了一些加強.prototype

function cloneAndStrengthen(proto){
    function F () {}
    F.prototype = proto
    let f = new F()
    f.say = function() { 
        console.log('I am a person')
    }
    return f
}
複製代碼

咱們看到上面的代碼,跟原型式繼承比,差異就是:在實例對象f返回以前,給f添加了一個say函數. 可是這樣在實例對象上添加的引用屬性(好比函數),跟構造函數模式同樣, 實例對象的引用類型屬性沒法共享,儘管這既是缺點也是優勢.code

三. 寄生組合式繼承
上一篇咱們提到的組合繼承其實也有個缺點,就是父類構造函數裏面的代碼會執行2遍,第一遍是在原型繼承的時候實例化父類, 第二遍是在子類的構造函數裏面借用父類的構造函數,咱們能夠用寄生組合式繼承來解決這個問題對象

function inherit(sub, super){
    let prototype = clone(super.prototype)
    prototype.constructor = sub    
    sub.prototype = prototype      
}
複製代碼

這樣咱們就實現了一個寄生組合式繼承的函數inherit,接下來咱們來使用一下:

function Person(name){}

function Student(){
    SuperType.call(this)
}

inherit(Student, Student)
複製代碼

咱們用 inherit 函數替換了 Student.prototype = new Person(),從而避免了執行 new Person().

書上說: 寄生組合式繼承是引用類型最理想的繼承範式.

關於js的繼承就介紹到這裏,感謝收看,若是以爲本文對您有用,請給本文的github加個star,萬分感謝, 另外,github上還有其餘一些關於前端的教程和組件,有興趣的童鞋能夠看看,大家的支持就是我最大的動力。

相關文章
相關標籤/搜索