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