前一篇文章簡單的介紹了 JavaScript 中的 class 以及他的語法,本篇文章將延續上一篇的基礎,進一步深入介紹:
extends如何建立繼承關係super()在建構子中的角色super.method()如何搭配覆寫(override)使用- 以及 class 背後真正的 prototype 運作原理
class 語法
- 用
class關鍵字宣告一個類別,建構函式與方法寫在大括號{}中 - 用
new關鍵字創建一個類別實例 obj.method()呼叫方法
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
greet(){
console.log(`Hi, I'm ${this.name}. I'm ${this.age} years old.`)
}
}
const elaine = new Person("Elaine", 18);
elaine.greet(); // Hi, I'm Elaine. I'm 18 years old.
extends
JavaScript 可以用 extends 關鍵字實作「類別繼承」,也就是讓另一個類別繼承已定義好的類別。
被繼承的類別叫做父類別或是基類,繼承而來的類別則是叫做子類別。
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
greet(){
console.log(`Hi, I'm ${this.name}, ${this.age} years old.`);
}
}
// Student 繼承 Person
class Student extends Person{
introduce(){
console.log(`I'm a student!`);
}
}
- 子類別可以使用父類別的方法,也可以定義自己的方法。
const elaine = new Student("Elaine", 18);
elaine.greet(); // Hi, I'm Elaine, 18 years old.
elaine.introduce(); // I'm a student!
extends 實際上做的是:
1.Object.setPrototypeOf(Student.prototype, Person.prototype)
2.Object.setPrototypeOf(Student, Person),因此子類別也會繼承父類別的靜態方法
super
super 有兩種用法:(1) 調用父類別的建構子 (2)在子類別中呼叫父類別方法
(1) super() 調用父類別的建構子
如果想在子類別的 constructor 中使用 this 關鍵字,必須先調用 super() 方法。
super() 會執行父類別的 constructor,並初始化子類別的 this。
class Student extends Person{
constructor(name, age, major){
// 呼叫 super()
super(name, age);
this.major = major;
}
introduce(){
console.log(`I'm a ${this.major} student!`);
}
}
const elaine = new Student("Elaine", 18, "Computer Science");
elaine.greet(); // Hi, I'm Elaine, 18 years old.
elaine.introduce(); // I'm a Computer Science student!
為何要呼叫 super()
因為子類別的實例同時也是父類別的實例,當我們實例化一個 Student 物件,其實是建立一個 Person 型別的物件,再加上一點 Student 自己的行為。
new Student("Elaine", 18, "Computer Science")
子類別的 constructor 叫做 derived constructor,這種建構子的特殊規則是不能建立自己的 this,必須呼叫 super(),才能取得初始化後的 this。
(2) 用 super.method() 呼叫父類別方法
super.method() 用來在子類別中呼叫父類別 prototype 上的方法,常會搭配覆寫(override) 一起使用,讓子類別在擴充父類別行為時保有原本的邏輯。
覆寫(override) 是在子類別中定義一個與父類別同名的方法。
如果想在子類別擴充父類別的方法,可以先用 super.method() 呼叫父類別的方法,再加入子類別自己的內容:
class Student extends Person{
constructor(name, age, major){
super(name, age);
this.major = major;
}
greet(){ // 宣告同名方法 ⭢ 覆寫
// 在子類別中呼叫父類別的 greet() 方法
super.greet();
// 加入子類別自己的行為
console.log(`I'm a ${this.major} student!`);
}
}
const elaine = new Student("Elaine", 18, "Computer Science");
elaine.greet(); // Hi, I'm Elaine, 18 years old. I'm a Computer Science student!
總結
ES6 的 class 語法讓 JavaScript 看起來更像傳統物件導向語言,但本質上仍然是基於 prototype 的繼承機制。
class本質上仍是 functionextends建立的是 prototype chainsuper()的作用是初始化子類別的thissuper.method()則是讓子類別可以在覆寫時保留父類別的邏輯






















