函式建構式
javascript沒有原生的class,是透過「原型」來繼承方法。透過函式建構式的方式,透過 new 關鍵字來產生新的物件。
1 2 3 4 5
| function Person(name) { this.name = name; }
let lucy = new Person('lucy');
|
但由於這種寫法與其他物件導向的程式語言差異太大,所以從ES6開始導入了Class語法。
Class語法糖
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Person { constructor(name) { this.name = name; };
greeting() { return `Hello this is ${this.name}`; };
const lucy = new Person('lucy'); console.log(lucy.greeting()) }
|
首先在class關鍵字後是class的名稱,內部的 constructor函式與原本的 建構函式 function Person(name) {} 是一樣的,greeting方法則直接寫入class裡。
Class與 constructor function的差異
- 函式可以被提升,而class不會,會出現「TDZ」暫時性死區
- 直接呼叫class名稱,而不是透過 new關鍵字來呼叫,會出現錯誤。
- class的區塊內所有程式碼,預設會進入嚴格模式。
getter 與 setter
在 Class 在取屬性值或設定屬性值時,可以直接這樣做:
1 2 3 4 5 6 7 8 9 10
| class Pizza { constructor(pizzaType) { this.type = pizzaType; }; }
const myPizza = new Pizza('tomato'); myPizza.type = 'supreme'; console.log(myPizza.type);
|
但如果有比較複雜的運用時,可以使用 Getter 和 Setter。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Pizza { constructor(pizzaType) { this.type = pizzaType; };
get pizzaType() { return this.type; }
set pizzaType(pizzaType) { this.type = pizzaType; }
const myPizza = new Pizza('tomato'); myPizza.pizzaType = 'sausage'; console.log(myPizza.pizzaType); }
|
getter 與 setter 的寫法也可以簡化成一個函式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Pizza { constructor(pizzaType) { this.type = pizzaType; };
getPizzaType() { return this.type; }
setPizzaType(pizzaType) { this.type = pizzaType; } }
const myPizza = new Pizza('tomato'); myPizza.setPizzaType('sausage'); myPizza.getPizzaType();
|
class 的靜態方法
class 裡面可以宣告靜態方法 (static method),其效果等同於直接定義一個方法在class的屬性上,不用new出新物件就可調用方法:
1 2 3 4 5 6 7
| class Article { static compare(a, b) { return a.date < b.date ? -1 : 1; } }
articles.sort(Article.compare);
|
extends 繼承類別
class可以用extends語法繼承。例如,想要 Rabbit class繼承自 Animal class。非常簡單,只要使用 class Rabbit extends Animal 語法:
1 2 3 4 5 6 7 8 9 10 11
| class Animal { run() { } } class Rabbit extends Animal { } let rabbit = new Rabbit(); rabbit.run();
|
super 覆寫方法
就像其他語言一樣,繼承的類別可以覆寫母類別的方法,但是通常我們不一定想要整個覆蓋掉母類別的方法,而是會根據既有的母類別的方法去延伸功能。想要延伸既有的方法,可以用 super 關鍵字,呼叫母類別的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Animal { run() { console.log('Animal run!'); } }
class Rabbit extends Animal { run() { super.run(); console.log('Rabbit jump!'); } }
|
super 覆寫 constructor
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Animal { constructor(name) { this.name = name; } }
class Rabbit extends Animal { constructor(name, earLength) { super(name); this.earLength = earLength; } }
let rabbit = new Rabbit('John', 5);
|
利用 super 關鍵字,在constructor內,呼叫母類別的 constructor。因為母類別已經有 this.name = name; 的邏輯了,不需要在子類別重寫一次 this.name = name ,直接呼叫 super(name); 就可以了。