Javascript繼承之道

原型賦值方式

上代碼

Javascript繼承之道

這種方法是直接new 了一個父類的實例,然後賦給子類的原型。這樣也就相當於直接將父類原型中的方法屬性以及掛在this上的各種方法屬性全賦給了子類的原型,簡單粗暴!

因為簡單粗暴,所以弊端很多

1, new實例的時候不能給父類傳參數

如上個例子所示,Sun 函數里面什麼都沒有,我們new的時候還怎麼傳參數,即使Sun函數體裡面有值,他也不能和Per函數建立聯繫

2,自己的prototype被佔用

為了繼承父類的實例直接賦值給了Sun.prototype,那Sun還怎麼用自己的prototype

調用構造函數方式

上代碼

Javascript繼承之道

在子類的在構造函數里用子類實例的this去調用父類的構造函數(改變this指向),從而達到繼承父類屬性的效果

但是這種方法卻不能繼承父類的prototype,所有sun調用不到sayName方法

組合繼承

上面兩種方法各有缺點,那能不能互補一下呢?

上代碼:

Javascript繼承之道

看似很完美,父類的屬性和方法都可以訪問到,還可以給父類傳遞參數

but 我們再看


Javascript繼承之道

這是什麼情況? name及出現了sun裡面也出現了sun的__proto__裡面。

看來組合方式繼承把兩個方式都有的也疊加了一切,實在是太不優雅

寄生組合繼承

這是目前es5中主流的繼承方式

上代碼:

Javascript繼承之道

這裡用到了Object.creat(obj)方法,該方法會對傳入的obj對象進行淺拷貝。和上面組合繼承的主要區別就是:將父類的原型複製給了子類原型。這種做法很清晰

但是也有一點小小弊端就是Per和Sun的constructor都指向了Pre,大部分情況下使用這種繼承方式沒問題,但是如果要使用constructor的話, 我們要加上這樣一句話

Sun.prototype.constructor = Sun

可以說,ES6之前實現繼承確實不是一件容易的事,特別和強類型語言對比來說,Javascript實現繼承只能用'另類'來說

但是現在,我們可以說Javascript站起啦!

ES6實現繼承

上代碼:


Javascript繼承之道

只能用兩個字來形容 優雅

但是為什麼Vue源碼中用構造函數而不用class呢?

歡迎留言談論...


分享到:


相關文章: