JavaScript的繼承方式
提示:僅是個人總結,可能有誤
文章目錄
- 原型鍊繼承
- 構造函數繼承
- 組合繼承(原型鍊+構造函數繼承)
- 原型式繼承
- 寄生式繼承
- 寄生組合式繼承
原型鍊繼承
父類執行個體作為子類原型對象
- 優點:繼承了父類的模闆,又繼承了父類的原型對象
- 缺點:無法實作多繼承,來自原型對象的所有屬性被所有執行個體共享,修改時會影響父類屬性;
/*直接繼承父類的原型對象,原型對象的constructor應該指向其構造函數,所
以必須寫第二行代碼;*/
Child.prototype = new Parent();
Child.prototype.constructor = Child;
構造函數繼承
在子類構造函數中使用 call() 調用父類構造函數
- 優點:解決了原型鍊繼承中不能傳參且引用值共享問題。
- 缺點:隻是繼承了父類執行個體對象的屬性,子類原型本身沒有改變,不能調用父類原型上的方法,因為 Children.prototype 和 Parent.prototype 根本沒有任何關系
/*在Children類中調用,相當于把Parent中的this替換為Children的this,創
建Children執行個體時就相當于運作Parent構造函數,但是此時Parent中的this
就是Children中的this,最後就等價于是Children聲明的執行個體相當于每個子
類都有父類執行個體的副本;*/
function Children(){
Parent.apply(this, arguments);
}
組合繼承(原型鍊+構造函數繼承)
同時書寫原型鍊繼承和構造函數繼承即可實作
- 優點:解決了原型鍊繼承中不能傳參且引用值共享問題以及構造函數繼承無法通路父類原型方法的問題。
- 缺點:調用兩次父類構造函數,占用記憶體;
原型式繼承
建立了一個臨時性的構造函數,然後将傳入的對象作為這個構造函數的原型,最後傳回這個臨時類型的一個新執行個體,本質上是一次淺複制;
- 缺點:無法複用函數;
/*//不能直接Children.prototype = Parent.prototype,如果使用,另一
個子類也繼承 Parent的話,如果Children或者該子類修改了他們對應的原型上
的方法的話,另外一個類的執行個體也會受到影響*/
function object(o) {
function F(){};
F.prototype = o;
return new F();
}
//使用
const parentObj = new Parent()
const childrenObj = object(parentObj)
寄生式繼承
在原型式繼承的基礎上再次包裝;
- 優點:解決了原型式繼承無法實作複用的問題;
function object(o) {
function F(){};
F.prototype = o;
return new F();
}
function Children(o) {
var clone = object(o);
clone.sayHi = function(){ // 增強對象,用于添加屬性或方法
console.log('hello, world');
}
return clone; // 傳回新對象
}
//使用
const parentObj = new Parent()
const childrenObj = Children(parentObj)
寄生組合式繼承
- 優點:解決了組合繼承調用兩次父類構造函數的問題;
function object(o) {
function F(){};
F.prototype = o;
return new F();
}
var o = object(Parent.prototype)//繼承父類原型
function Children(){
Parent.call(this)//繼承父類構造函數的屬性
}
Children.prototype = o;
o.constructor = Children
const parentObj = new Parent()
希望對您有幫助!!!