原型賦值方式
上代碼
這種方法是直接new 了一個父類的實例,然後賦給子類的原型。這樣也就相當於直接將父類原型中的方法屬性以及掛在this上的各種方法屬性全賦給了子類的原型,簡單粗暴!
因為簡單粗暴,所以弊端很多
1, new實例的時候不能給父類傳參數
如上個例子所示,Sun 函數里面什麼都沒有,我們new的時候還怎麼傳參數,即使Sun函數體裡面有值,他也不能和Per函數建立聯繫
2,自己的prototype被佔用
為了繼承父類的實例直接賦值給了Sun.prototype,那Sun還怎麼用自己的prototype
調用構造函數方式
上代碼
在子類的在構造函數里用子類實例的this去調用父類的構造函數(改變this指向),從而達到繼承父類屬性的效果
但是這種方法卻不能繼承父類的prototype,所有sun調用不到sayName方法
組合繼承
上面兩種方法各有缺點,那能不能互補一下呢?
上代碼:
看似很完美,父類的屬性和方法都可以訪問到,還可以給父類傳遞參數
but 我們再看
這是什麼情況? name及出現了sun裡面也出現了sun的__proto__裡面。
看來組合方式繼承把兩個方式都有的也疊加了一切,實在是太不優雅
寄生組合繼承
這是目前es5中主流的繼承方式
上代碼:
這裡用到了Object.creat(obj)方法,該方法會對傳入的obj對象進行淺拷貝。和上面組合繼承的主要區別就是:將父類的原型複製給了子類原型。這種做法很清晰
但是也有一點小小弊端就是Per和Sun的constructor都指向了Pre,大部分情況下使用這種繼承方式沒問題,但是如果要使用constructor的話, 我們要加上這樣一句話
Sun.prototype.constructor = Sun
可以說,ES6之前實現繼承確實不是一件容易的事,特別和強類型語言對比來說,Javascript實現繼承只能用'另類'來說
但是現在,我們可以說Javascript站起啦!
ES6實現繼承
上代碼:
只能用兩個字來形容 優雅
但是為什麼Vue源碼中用構造函數而不用class呢?
歡迎留言談論...