在上一篇 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上還有其餘一些關於前端的教程和組件,有興趣的童鞋能夠看看,大家的支持就是我最大的動力。