你知道JavaScript的繼承有幾種寫法嗎?
標題的靈感來源於魯迅的小說《孔乙己》中孔乙己和小夥計的一段對話:“茴香豆的茴字,怎樣寫的?……回字有四樣寫法,你知道麼?”
這裡我們並不探討封建制度下窮苦潦倒的讀書人的迂腐,回字的幾種寫法留給漢語言的同學去研究吧,今天我們討論JavaScript
繼承的幾種寫法,由淺入深,一層層剝開她的面紗,最後給出一個最佳實踐。
一、通過建構函式實現繼承
function Parent() {
this.name = 'name';
}
Parent.prototype.say = function () {
console.log('say');
}
function Child() {
Parent.call(this);
this.type = 'child';
}
const child = new Child();
這種方式通過在子類的建構函式中呼叫父建構函式實現繼承,但是有個致命的缺點:如下圖,子類例項並不能繼承父類中原型物件上的屬性或者方法。
二、通過原型物件實現繼承
function Parent() {
this.name = 'name';
this.favor = ['blue', 'red'];
}
Parent.prototype.say = function () {
console.log('say');
}
function Child() {
this.type = 'child';
}
Child.prototype = new Parent();
const child = new Child();
這種方式通過給子類建構函式的prototype
物件賦值實現繼承,如下圖,無論是name
屬性還是say
方法都能被子類例項訪問到。
但是這種方式也有缺點,如下圖,當父類的屬性是引用型別時,子類例項繼承的是同一份屬性,任一例項改變該屬性都會引起全域性變化,無法互相隔離。
三、組合方式
function Parent() {
this.name = 'name';
this.favor = ['blue', 'red'];
}
Parent.prototype.say = function () {
console.log('say');
}
function Child() {
Parent.call(this);
this.type = 'child';
}
Child.prototype = new Parent();
const child = new Child();
結合了上兩種方式,避免了上面的缺點。但是這種方式在每次例項化子類例項時,都會呼叫兩次父類建構函式,需要優化。
四、組合優化①
function Parent() {
this.name = 'name';
this.favor = ['blue', 'red'];
}
Parent.prototype.say = function () {
console.log('say');
}
function Child() {
Parent.call(this);
this.type = 'child';
}
Child.prototype = Parent.prototype;
const child = new Child();
在給子類prototype
賦值時不要採用例項化父類的方式,直接賦值父類的prototype
。
其實,這種方式也有缺點:如下圖,子類例項的constructor
屬性直接指向了父類建構函式,導致無法判斷當前物件例項化自哪個建構函式。
五、組合優化②
function Parent() {
this.name = 'name';
this.favor = ['blue', 'red'];
}
Parent.prototype.say = function () {
console.log('say');
}
function Child() {
Parent.call(this);
this.type = 'child';
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
const child = new Child();
終極改造完成:通過Object.create()
方法指定了子類例項的__proto__
屬性,同時顯式宣告子類的constructor
。
相關文章
- JavaScript的幾種繼承方式JavaScript繼承
- 你不知道的javascript之繼承JavaScript繼承
- 回字有四種寫法,那你知道單例有五種寫法嗎單例
- javascript幾種繼承方式;不看就out啦JavaScript繼承
- 單例模式的七種寫法,你都知道嗎?單例模式
- JavaScript中的六種繼承JavaScript繼承
- 【前端詞典】繼承(二) - 回的八種寫法前端繼承
- cache 有幾種寫法,你都會了麼?
- JS繼承有哪些,你能否手寫其中一兩種呢?JS繼承
- JavaScript 中的六種繼承方式JavaScript繼承
- JavaScript常用八種繼承方案JavaScript繼承
- 深入 JavaScript 常用的8種繼承方案JavaScript繼承
- 單例模式有幾種寫法?單例模式
- 你真的理解JS的繼承了嗎?JS繼承
- 八、目前JDK中,單例模式這3種寫法你知道嗎?JDK單例模式
- Javascript繼承4:潔淨的繼承者—-原型式繼承JavaScript繼承原型
- 單例模式你會幾種寫法?單例模式
- JavaScript繼承JavaScript繼承
- JavaScript 繼承JavaScript繼承
- javascript:繼承JavaScript繼承
- 實現繼承的幾種方式及工作原理繼承
- JS 總結之原型繼承的幾種方式JS原型繼承
- Linux程式間通訊有幾種方式?這8個你都知道嗎?Linux
- switch 有四樣寫法你知道麼
- JavaScript中class繼承超乎你的想象《一》JavaScript繼承
- 【前端詞典】繼承(二) - 回的八種寫法·面試必問前端繼承面試
- JavaScript中的繼承JavaScript繼承
- Javascript 五十問——實現的繼承多種方式JavaScript繼承
- JavaScript繼承的多種方式和優缺點JavaScript繼承
- js實現繼承的幾種方式和對比JS繼承
- 你不知道的事---SringCloud的feign的繼承特性GCCloud繼承
- JavaScript class 繼承JavaScript繼承
- JavaScript extends 繼承JavaScript繼承
- javascript之繼承JavaScript繼承
- Javascript繼承2:建立即繼承—-建構函式繼承JavaScript繼承函式
- 6種JavaScript繼承方式及優缺點JavaScript繼承
- Linux驅動實踐:你知道【字元裝置驅動程式】的兩種寫法嗎?Linux字元
- 孔乙己的疑問:單例模式有幾種寫法單例模式