本文主要內容為探討另一個建立物件和設定原型的方法「ES6 Class」的相關知識。
ES6 與類別 (Classes)
在其他程式語言中 Class 比較偏向是一個模版,而不是一個物件,它只是在告訴我們物件的模樣,直到用 new 關鍵字才會真的建立物件。
然而,JavaScript ES6 的 Class 卻是一個已經被建立的物件,我們只是再用 new 關鍵字從這個物件去建立新物件而已。
不過這也沒問題,畢竟不同程式語言,也沒必要完全照著走嘛 🙄 但是,這有可能就會造成從其他程式語言轉換過來的人,容易誤解了原型繼承的概念,因為像是習慣寫 Java 的人就會把 Class 當作模版來使用。
總而言之,這篇介紹的 ES6 Class 與前篇介紹的 Object.create,都比第一個講的函式建構子好用許多喔!
STEP 1:用 class 定義物件
- 建構子 (constructor)
- 方法 (methods)
class Person {
// 建構子 (constructor):就像是函式建構子一樣,預先設定它們的值
constructor(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
// 可以直接取用這邊放的方法
greet() {
return "Hi " + this.firstname;
}
}
var damao = new Person("Damao", "Huang");
console.log(damao); // Person {firstname: "Damao", lastname: "Huang"}
console.log(damao.greet()); // Hi Damao
STEP 2:用 extends 設定原型
這裡使用了 extends
來設定原型,它的效果就相當於 InformalPerson.__proto__ = Person
,所以在這邊 Person
就是 InformalPerson
的原型。
class InformalPerson extends Person {
// 呼叫原型物件的建構子
constructor(firstname, lastname) {
super(firstname, lastname);
}
// 呼叫父類別的方法
greetPerson() {
return super.greet();
}
// 可以在子類別中覆寫父類別的方法
greet() {
return "Yo! " + this.firstname;
}
}
var sean = new InformalPerson("Sean", "Huang");
console.log(sean); // InformalPerson {firstname: "Sean", lastname: "Huang"}
console.log(sean.greetPerson()); // Hi Sean
console.log(sean.greet()); // Yo! Sean
這邊有一個重點就是 super
關鍵字:
- 如果在子類別的 constructor 中使用
super()
,就會呼叫原型物件的 constructor,如此一來就能夠傳入初始值到原型鏈裡面 - 如果想要在子類別中,呼叫父類別的方法來使用,也可以透過
super
這個關鍵字。當super
不加括號時,代表把super
當物件使用,此時super
會指向父類別Person
另外,也可以在子類別中設定一樣的方法名稱,這麼做的話可以隱藏或覆寫父類別的方法。
語法糖 (Syntactic Sugar)
我們總共提到了三種「建立物件和設定原型」的方法,但其實這些只是不同的語法表達的方式而已,它們底層的原理都是一樣的。
這種狀況我們會說這是 JavaScript 的語法糖 (Syntactic Sugar),表示有很多種不同的方法都可以做到同一件事。
像是函式建構子、Object.create,與 ES6 的 Class,它們本質上都是在做同一件事,我們使用這三種方法時,JavaScript 引擎都是在做原型繼承。
回顧
看完這篇文章,我們到底有什麼收穫呢?藉由本文可以理解到…
- 使用 ES6 Class 建立物件和設定原型
- 語法糖讓程式更加簡潔,有更高的可讀性