總結概括了6種js的繼承實現方式並分析了其中實現的區別,爲了解釋,定義一個做爲的父類的類型Animal,以後定義的類都爲Animal類的子類,實現方式不一樣,Animal類代碼以下:bash
function Animal(name) {
this.name = name;
this.color = 'blue';
}
Animal.prototype.sayName = function () {
console.log(this.name);
};
複製代碼
這種是最簡單的實現繼承的方式,即便子類的原型對象等於父類的一個新的實例對象,舉例代碼以下:函數
// 1.原型鏈繼承
function Cat() {
}
Cat.prototype = new Animal();
複製代碼
這樣即實現了Cat類對Animal類的繼承,其中存在的問題是Cat的原型對象中會有Animal類的構造函數中的屬性如上例中的color屬性,而這個屬性是沒必要要的。並且Cat.prototype的constructor屬性也是指向Animal的。實現繼承後關係如圖所示:ui
借用構造函數繼承也叫僞造對象繼承或者經典繼承,其主要實現方式是在子類的構造函數中調用父類的構造函數,示例代碼以下:this
// 2.借用構造函數,經典繼承
function Dog() {
// 繼承Animal,並傳遞參數
Animal.call(this, 'doge');
}
var instance = new Dog();
複製代碼
這種方式的好處是能夠向父類傳遞參數,並且父類的原型對象中的屬性及方法對子類型也是不可見的,因此這種方法不多單獨使用。spa
這種繼承的方式結合了借用構造函數繼承和簡單的原型鏈繼承,示例代碼以下:prototype
// 3.組合繼承
function Mouse() {
Animal.call(this, 'jerry');
}
// 繼承方法
Mouse.prototype = new Animal();
Mouse.constructor = Mouse;
複製代碼
這種繼承方式是js中最經常使用的繼承模式,可是其中仍然沒有解決原型鏈繼承問題中存在的子類原型對象中存在父類構造函數中屬性的問題。code
這種繼承方式主要針對與不關注自定義類型和構造函數而考慮對象的狀況下,思路是基於已有的對象建立新對象,實例代碼以下:cdn
// 4.原型式繼承
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
var bird1 = object(Animal);
複製代碼
這種繼承方式經過臨時建立一個新的構造函數F並將其原型對象設爲所須要的對象,而後返回一個此構造函數F的實例以實現繼承。關係圖以下:對象
Object.create()
規範化了原型式繼承,上面的代碼能夠改成:
var bird2 = Object.create(Animal, {number: {value: 3}});
複製代碼
同時在Object.create()
中能夠在第二參數中實現定義額外的屬性,bird2相對bird1多了一個value屬性。在只有一個參數時上方定義的object()函數和Object.create()函數行爲相同。blog
這種繼承方式使用了Object.create()
,建立一個用於封裝繼承過程的函數,在函數內部來加強對象,其本質原理與原型式繼承相似,示例代碼:
// 5.寄生式繼承
function createAnother(original) {
var clone = Object.create(original);
clone.sayHi = function () {
console.log('hi');
};
return clone;
}
var anotherAnimal = createAnother(Animal);
anotherAnimal.sayHi();
複製代碼
寄生組合式繼承是最理想的繼承範式,經過借用構造函數來繼承屬性,經過原型鏈來繼承方法。本質上使用了寄生式繼承來繼承超類型的原型,而後將結果指定給子類型的原型。實例代碼以下:
// 6.寄生組合式繼承
function inheritPrototype(subType, superType) {
// 建立對象
var prototype = Object.create(superType.prototype);
// 加強對象
prototype.constructor = subType;
// 指定對象
subType.prototype = prototype;
}
function Fish(name) {
Animal.call(this, 'fish');
}
inheritPrototype(Fish, Animal);
複製代碼
使用結果示意圖以下: