引言
在 ES5 中,繼承的方式有原型繼承,構造繼承,原型組合繼承,寄生式繼承,寄生組合繼承。
其實原型組合繼承就是原型繼承與構造繼承的組合,而寄生組合繼承則是寄生式繼承和構造繼承的組合。不盡會猜想是否寄生式繼承是原型繼承的某種替代方案?如果是的話,那究竟是爲什麼要選擇寄生繼承呢?請往下看:
繼承方式
1. 原型組合繼承
function Father(){
this.msg = "Hello"
}
Father.prototype.say = function(){console.log(this.msg)}
function Child(){
Father.call(this); // 第一次:通過 call 調用父構造函數
this.childMsg = 'child';
}
Child.prototype = new Father(); // 第二次:new 本質上也調用了父構造函數
Child.prototype.run = function(){console.log(this.msg +' '+ this.childMsg)}
let child = new Child();
child.run();
child.say();
2. 寄生組合繼承
function inheritProperty(Child,Father){
let prototype = Object.create(Father.prototype);
prototype.constructor = Child;
Child.prototype = prototype
}
function Father(){
this.msg = "Hello"
}
Father.prototype.say = function(){console.log(this.msg)}
function Child(){
Father.call(this); // // 第一次:通過 call 調用父構造函數
this.childMsg = 'child';
}
inheritProperty(Child,Father); // 替換 Child.prototype = new Father();
Child.prototype.run = function(){console.log(this.msg +' '+ this.childMsg)}
let child = new Child();
child.run();
child.say();
可以看出寄生組合繼承與原型組合繼承非常類似,只是有一行被替換了。寄生組合繼承與原型組合繼承相比,寄生組合繼承少調用一次父構造函數。寄生組合繼承之所以可以調用一次是因爲它引入了一個空函數,將父構造函數的原型對象賦予此空函數,然後再將這個空函數的實例賦予子構造函數的原型對象。其實他也調用的兩次函數,只不過第二次調用的是空函數,當然比調用父函數的開銷要小了,所以寄生組合繼承也被都被普遍認爲是最理想的繼承實現方式。