2019年本命年已經夠坎坷了,沒想到2020開局更難,因疫情緣由,公司公告說爲了可持續發展,1月工資要等疫情穩定後在發放,當時內心就不平衡,原本打算再好好幹半年,公司這邊操做真是猝不及防,那好吧,次日我直接提了離職繼續在家躺屍,躺了20多天也累了,昨天回了長沙,準備好好複習一下基礎知識,而後再是把駕照拿了,再去廣州或深圳發展,不想再呆小公司了,太不靠譜了。javascript
javascript中有不少種繼承方式,好比組合繼承,原型式繼承,寄生式繼承等,而寄生組合式繼承結合了上面繼承方式的優勢,避免了其缺陷。寄生組合式繼承的大體實現邏輯爲經過借用構造函數來繼承屬性,經過原型鏈的混成形式來繼承方法。html
代碼截取自Vue-0.1的源碼, 沒想到吧!Vue的源碼裏面包含我今天要複習的知識點。vue
function ViewModel(){
// .....
}
ViewModel.extend = extend
function extend (options) {
var ParentVM = this
var ExtendedVM = function (opts, asParent) {
if (!asParent) {
opts = inheritOptions(opts, options, true)
}
ParentVM.call(this, opts, true)
}
// ExtendedVM.prototype繼承ParentVM.prototype
var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype)
// prototype的constructor指向構造函數
utils.defProtected(proto, 'constructor', ExtendedVM)
return ExtendedVM
}
複製代碼
下面解釋一下上面的代碼:java
Object.create(ParentVM.prototype)
,爲建立的副本添加 constructor 屬性,從而彌補因重寫原型而失去的默認的 constructor 屬性utils.defProtected(proto, 'constructor', ExtendedVM)
,將新建立的對象(即副本)賦值給子類型的原型。在ExtendedVM中調用父類的構造函數ParentVM.call(this, opts, true)
來繼承不可共享的屬性。git
const ChildVue = ViewModel.extend({})
child = new ChildVue() // 這個裏面調用ViewModel的構造函數
複製代碼
這個例子的高效率體如今它只調用了一次 ViewModel構造函數,而且所以避免了在 ChildVue.prototype 上面建立沒必要要的、多餘的屬性。與此同時,原型鏈還保持不變。github
寫到這裏差很少已經寫完了,下次面試官問你寄生組合式繼承能夠直接搬Vue的源碼跟他聊,這時他看到你還不差的回答,可能會問上面的代碼中Object.create的內部是怎麼實現的,別急,下面這段代碼告訴你Object.create怎麼實現:面試
var _create = function (o) {
var F = function () {}
F.prototype = o
return new F()
}
// 或者也能夠這樣
_create = function (o){
var t = {}
t.__proto__ = o
return t
}
複製代碼
看到這,面試官可能會問__proto__
與prototype
的區別以及原型鏈相關的知識了,別擔憂, 我在掘金上看到了一篇講原型鏈特別好的文章(不是我寫的,他寫的太好了,忍不住推薦),我如今推薦給你。ide
幫你完全搞懂JS中的prototype、__proto__與constructor(圖解)函數
再推薦一篇相關的文章給你,也是關於javascript繼承的,他們的文章都寫的太好了post