本系列文章經過重新編排和擴充,已出書為ECMAScript關鍵30天。原始文章因當時準備時程緊迫,多少有些許錯誤。為了避免造成讀者的困擾,以及配合書籍的內容規劃,將會陸續更新本系列文章。
本篇文章在 2021/11/8 已更新。
在 Javascript 中,實體的建立機制主要是 prototype-based為基礎的物件導向設計。在 ES5,我們需要新增建構函式,來產生所謂的原型,並以 prototype
進行原型的擴充,最後再以 new
的關鍵字建立實體。
在 ES2015 推出了class
,在寫法上跟class-based為基礎的物件導向設計很相似,但是骨子裡還是 prototype-based 的機制。所以只能說是 ES5 寫法上的語法糖,在使用上需要注意。
接著就直接從關鍵字簡要說明,來看看怎麼寫類別吧。
class
&constructor
以 class
加上類別名稱進行宣告。 class Anime { //... }
當以 new
建立實體時,如果要對傳入的參數進行初始化的話,可在 constructor
的程式區塊中執行。
class Comic {
constructor(name) {
this.name = name;
}
printName() {
return `NAME:${this.name}`;
}
}
let c = new Comic("One Punch Man");
c.printName(); // NAME: "One Punch Man"
super
& extends
super
的關鍵字有兩個使用時機
super()
傳入super.XXX
取得子類別可透過 extends
來繼承父類別。以原型的說法來表示的話,父子類別就是一種原型鏈的表示。
class Anime extends Comic {
constructor(name, op) {
super(name);
this.op = op;
}
printName() {
return `${super.printName()}(動畫)`;
}
printOP() {
return `OP:${this.op}`;
}
}
let a = new Anime("彼女、お借りします", "センチメートル");
a.printOP(); // "OP:センチメートル"
set
& get
在方法前面加上前綴字 - set
或 get
,可設定屬性的輸出(Getter)與輸入(Setter)。 Getter 和 Setter 的名稱需相同。使用情境常用來模擬私有成員的存取限制。
當使用 Setter 時,直接以等號指派值進去即可。而當類別只有 Setter 時,表示此屬性僅能設值,而無法取值。
class Anime extends Comic {
constructor(name, op) {
super(name);
this.op = op;
}
printName() {
return `${super.printName()}(動畫)`;
}
printOP() {
return `OP:${this.op}`;
}
set year(value) {
this._year = value;
}
get year() {
return this._year;
}
}
let a = new Anime("Re:0");
a.year = 2020;
console.log(a.year); // 2020
static
如果要宣告類別的靜態方法的話,可以在方法實作前面加 static
前綴字。
class Comic {
constructor(name, author) {
this.name = name;
}
printName() {
return `NAME:${this.name}`;
}
static printInfo() {
console.log("This is Comic Class");
}
}
let a = new Anime("Re:0", "STYX HELIX");
a.printInfo(); // Error a.printInfo is not a function
Comic.printInfo(); // This is Comic Class
今天了解如何以類別建立實體模型,這樣的寫法雖然貼近大型架構用的語言(Java, C#等),但底層的機制仍不大一樣。所以在開發時,需要注意在繼承或擴充類別時,是否會造成其他類別或實體的影響喔。