JavaScript之構造函數繼承和組合繼承的優缺點


一.構造函數繼承

  1. 構造函數繼承的基本思路是在子類型的構造函數中,調用要繼承的構造函數,具體實現如下:
function Parent() {
  this.name = ["heyushuo", "kebi"];
}

function Child() {
  Parent.call(this);
  // 或者 Parent.apply(this);
}

var Person1 = new Child();
Person1.name.push("kuli");
console.log(Person1.name); //["heyushuo", "kebi","kuli"];
var Person2 = new Child();
console.log(Person2.name); //["heyushuo", "kebi"];
// 通過上邊的兩個打印,Child的兩個實例繼承的name屬性不會互相影響
// 因為,創建Child實例的環境下調用Parent構造函數,這樣可以使得每個實例都會具有自己的name屬性,所以兩個不會互相影響

2. 優點(可以傳遞參數)

function Parent(name) {
  this.name = name;
}

function Child() {
  Parent.call(this, "heyushuo");
  //或者Parent.apply(this, ["heyushuo"]);
}
var Person = new Child();
console.log(Person.name); //heyushuo

// 需要注意的:為了確保Parent構造函數不會重寫子類型的屬性,需要在Parent.call(this)之后在定義子類型中的屬性

3.構造函數的缺點

因為方法和屬性只能寫在構造函數中,因此不能實現函數復用 只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法 (原型中定義的方法和屬性對於子類是不可見的)

二.組合繼承(原型鏈和構造函數組合式繼承)

通俗來講就是用原型鏈實現對原型屬性和方法的繼承,用借用構造函數繼承來實現對實例屬性的繼承。

function Parent(name) {
  this.name = name;
  this.newArr = ["red", "blue", "green"];
}
Parent.prototype.sayName = function() {
  console.log(this.name);
};

function Child(name) {
  Parent.call(this, name);
  this.age = 26;
}

Child.prototype = new Parent();
//重寫Child.prototype的constructor屬性,使其執行自己的構造函數Child
Child.prototype.constructor = Child;
Child.prototype.sayAge = function() {
  console.log(this.age);
};

var Person1 = new Child("heyushuo");
console.log(Person1);
Person1.newArr.push("yellow");
console.log(Person.newArr); //["red", "blue", "green","yellow"]
Person.sayName(); //heyushuo

var Person2 = new Child("kebi");
console.log(Person2.newArr); //["red", "blue", "green"]
Person.sayName(); //kebi

通過一張圖來看一下:

總結

  1. 組合式繼承避免了原型鏈和構造函數的缺陷,融合了他們的有點,成為最常用的繼承模式
  2. 組合式繼承有一個缺點, 如上圖可以看出, 創建的實例和原型上存在兩份相同的屬性即(name 和 newArr);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM