js的繼承方式有很多,本文主要介紹以下幾種:構造函數繼承、原型鏈繼承、組合繼承、es6中的class繼承這四種。
一、構造函數繼承
構造函數一般命名時首字母大寫,用來區分於普通函數,內部使用的this對象來指向即將要生成的實例對象,使用New來生成實例對象。
// 這是一個構造函數
function Animal(name) {
this.name = name;
this.showName = function() {
console.log(this.name);
};
}
function Cat(name) {
Animal.call(this, name);
//Animal.bind(this)(name)
//Animal.apply(this, [name])
}
let cat = new Cat("我是一隻貓");
cat.showName();
補充知識:
call、apply、bind方法的作用都是改變函數的執行環境,第一個參數傳入上下文執行環境(this),然後傳入函數執行所需的參數。
優點:
- 可以在子類型構造函數中向Parent傳遞參數
- 避免了引用類型的屬性被所有實例共享
缺點:
- 只能繼承構造函數中的屬性和方法,而無法繼承原型鏈上的屬性和方法
二、原型鏈繼承
利用原型鏈來實現繼承就是讓父類的一個實例作爲子類的原型
// 這是一個構造函數
function Animal(name) {
this.name = name;
this.showName = function() {
console.log(this.name);
};
}
function Cat() {}
//父類的一個實例作爲子類的原型
Cat.prototype = new Animal("我是一隻貓");
// 注意這裏new Animal()生成的父類對象並沒有constructor屬性,故需添加上
Cat.prototype.constructor = Cat;
let cat = new Cat();
cat.showName();
優點:
- 能夠繼承父類構造函數及其原型鏈上的全部屬性和方法
缺點:
- 引用類型的屬性被所有實例共享,一改全改
- 在創建 Child 的實例時,不能向Parent傳參
三、組合繼承
組合構造函數及原型鏈兩種繼承方法,從而解決他們存在的缺點
// 這是一個構造函數
function Animal(name) {
this.name = name;
this.showName = function() {
console.log(this.name);
};
}
function Cat(name) {
Animal.apply(this, [name]); //第二次調用
}
//父類的一個實例作爲子類的原型
Cat.prototype = new Animal();
// 注意這裏new Animal()生成的父類對象並沒有constructor屬性,故需添加上
Cat.prototype.constructor = Cat;
let cat = new Cat("我是一隻貓");
cat.showName();
優點:
- 解決了原型鏈繼承和構造函數繼承存在的問題
缺點:
- 父類的構造函數被調用兩次
四、class繼承
利用ES6中的extends,寫法更加面向對象,原理還是原型鏈
class Animal {
constructor(name) {
this.name = name;
}
showName() {
console.log(this.name);
}
}
class Cat extends Animal {
constructor(name) {
super(name); //不能少,而且必須寫在this前邊
this.type = "寵物";
}
showType() {
console.log(this.type);
}
}
let cat = new Cat("我是一隻貓");
cat.showName();
cat.showType();
優點:
- 實現更簡單,且不存在不能傳參等問題
補充知識super :
super關鍵字可以當作函數
super()
使用,也可以當作對象super
使用1.當做函數使用
在constructor中,表示父類的構造函數,並且子類的構造函數必須執行一次super,即
super(name)
相當parent.prototype.constructor.call(this,name)
constructor(name) { super(name); this.type = "寵物"; }
super()也可寫在子類的構造函數中,寫在自定義函數中會報錯。
2.當做對象使用
在靜態方法中指向父類,在普通方法中指向父類的原型