舉例說明js如何實現繼承?

王铁柱6發表於2024-11-24

JS實現繼承主要有以下幾種方式,我將分別舉例說明:

1. 原型鏈繼承:

這是最基本的繼承方式,核心是將子型別的原型指向父型別的例項。

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

Parent.prototype.sayName = function() {
  console.log("My name is " + this.name);
};

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

Child.prototype = new Parent("Parent Name"); // Child的原型指向Parent的例項
Child.prototype.constructor = Child; // 修正constructor指向

let child1 = new Child("Child Name", 10);
child1.sayName(); // 輸出: My name is Parent Name  (繼承自Parent)
console.log(child1.age); // 輸出: 10
console.log(child1 instanceof Parent); // 輸出: true
console.log(child1 instanceof Child); // 輸出: true

優點: 簡單易懂。

缺點:

  • 所有子類例項共享父類例項的屬性,修改一個例項的屬性會影響其他例項。
  • 建立子類例項時無法向父類建構函式傳參。

2. 建構函式繼承 (借用建構函式):

透過在子型別建構函式中呼叫父型別建構函式來繼承父型別的屬性。

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

function Child(name, age) {
  Parent.call(this, name); // 呼叫Parent建構函式
  this.age = age;
}

let child1 = new Child("Child Name", 10);
child1.sayName(); // 報錯: child1.sayName is not a function (沒有繼承父類方法)
console.log(child1.name); // 輸出: Child Name
console.log(child1.age); // 輸出: 10
console.log(child1 instanceof Parent); // 輸出: false
console.log(child1 instanceof Child); // 輸出: true

優點:

  • 解決了原型鏈繼承共享屬性的問題。
  • 可以在建立子類例項時向父類建構函式傳參。

缺點:

  • 無法繼承父類原型上的方法和屬性,只能繼承父類建構函式中的屬性。
  • 每次建立子類例項都會重複執行父類建構函式中的程式碼,造成效能浪費。

3. 組合繼承 (原型鏈繼承 + 建構函式繼承):

結合了原型鏈繼承和建構函式繼承的優點。

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

Parent.prototype.sayName = function() {
  console.log("My name is " + this.name);
};

function Child(name, age) {
  Parent.call(this, name); // 繼承屬性
  this.age = age;
}

Child.prototype = Object.create(Parent.prototype); // 繼承方法
Child.prototype.constructor = Child; // 修正constructor指向

let child1 = new Child("Child Name", 10);
child1.sayName(); // 輸出: My name is Child Name
console.log(child1.age); // 輸出: 10
console.log(child1 instanceof Parent); // 輸出: true
console.log(child1 instanceof Child); // 輸出: true

優點: 結合了兩種繼承方式的優點,既可以繼承父類建構函式中的屬性,也可以繼承父類原型上的方法。

缺點: 父類建構函式會被呼叫兩次(一次在建立子類原型時,一次在子類建構函式中),造成一定的效能浪費。

4. ES6 Class 繼承 (extends):

ES6 提供了更簡潔的 class 語法和 extends 關鍵字來實現繼承。

class Parent {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log("My name is " + this.name);
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name); // 呼叫父類建構函式
    this.age = age;
  }
}

let child1 = new Child("Child Name", 10);
child1.sayName(); // 輸出: My name is Child Name
console.log(child1.age); // 輸出: 10
console.log(child1 instanceof Parent); // 輸出: true
console.log(child1 instanceof Child);

相關文章