結合vue源碼複習javascript寄生組合式繼承

文章背景

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

繼承方法

  1. ViewModel爲超類型構造函數或者能夠稱爲父類構造函數
  2. ExtendedVM爲子類型構造函數
  3. 在函數內部,建立父類型原型的一個副本, 這行代碼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

寄生組合式繼承

相關文章
相關標籤/搜索