在class中可以使用靜態(static),將某個方法(method)或某個屬性(property)放在某個class中,或者讓其他class去繼承,並讓class能單獨使用這些方法和屬性。
首先,class本身沒辦法直接使用method:
class Competition{
constructor(competitionName,date){
this.competitionName = competitionName;
this.competitionDate = date;
}
competitionNews(){
return `The ${this.competitionName} competition will be held on ${this.competitionDate}.`;
}
}
console.log(Competition.competitionNews())
在方法前面加上靜態關鍵字,但會發現沒辦法使用this
,因為class本身是用來創建實例,而這些this
是給即將變成實例的物件使用。
class Competition{
constructor(competitionName,date){
this.competitionName = competitionName;
this.competitionDate = date;
}
static competitionNews(competitionName,date){
return `The ${this.competitionName} competition will be held on ${this.competitionDate}.`;
}
}
console.log(Competition.competitionNews('hot pot','October 40th'))//The undefined competition will be held on undefined.
因此將靜態方法中回傳的內容改成傳入的參數,並新增一個實例嘗試讓實例使用類的方法,會報錯。
class Competition{
constructor(competitionName,date){
this.competitionName = competitionName;
this.competitionDate = date;
}
static competitionNews(competitionName,date){
return `The ${competitionName} competition will be held on ${date}.`;
}
}
console.log(Competition.competitionNews('hot pot','October 40th'))//The hot pot competition will be held on October 40th.
//新增一個實例
const hotpotCompetition = new Competition('hot pot','October 40th')
console.log(hotpotCompetition);/
//Competition {
// competitionName: 'hot pot',
// competitionDate: 'October 40th'
// }
console.log(hotpotCompetition.competitionNews('hot pot','October 40th');
//TypeError: hotpotCompetition.competitionNews is not a function
靜態屬性等同靜態方法的原理,寫在constructor
外面。
class Competition{
static competitionName = 'hot pot'
static competitionDate = 'October 40th'
}
console.log(Competition.competitionName);//'hot pot'
可以讓靜態方法繼承給其他的類:
class Competition{
static competitionNews(competitionName,date){
return `The ${competitionName} competition will be held on ${date}.`;
}
}
class Contestant extends Competition {
constructor(contestantName){
super()
this.contestantName = contestantName;
sayName(){
return `My name is ${this.contestantName}. `;
}
}
console.log(Contestant.competitionNews('hot pot','October 40th'));
在class中,可以使用類字段(Class fields)先在constructor
外面的定義屬性,預設上來說,類字段都會是公開(public)的,且存在於class每個創建的實例中。沒有初始化的類字段就會是undefined。
class Competition{
competitionName = 'hot pot';
competitionDate
}
const hotpotCompetition = new Competition();
console.log(hotpotCompetition.competitionName);//hot pot
console.log(hotpotCompetition.competitionDate);//undefined
受保護的屬性用#
符號為開頭,讓這些字段能夠變成私人的狀態。
先以一般的class的範例:
class Competition{
competitionName = 'hot pot';
constructor(date){
this.competitionDate = date;
}
competitionNews(competitionName,date){
return `The ${competitionName} competition will be held on ${date}.`;
}
}
const hotpotCompetition = new Competition('October 40th');
console.log(hotpotCompetition.competitionName);//hot pot
console.log(hotpotCompetition.competitionDate);//October 40th
console.log(hotpotCompetition.competitionNews('hot pot','October 40th'));//The hot pot competition will be held on October 40th.
把上面的字段跟方法等內容都加上#
:
class Competition{
#competitionName = 'hot pot';
constructor(date){
this.#competitionDate = date;
}
#competitionNews(competitionName,date){
return `The ${competitionName} competition will be held on ${date}.`;
}
}
//SyntaxError: Private field '#competitionDate' must be declared in an enclosing class
就會發現constructor中的私有字段是錯誤的,需要先在外面先宣告。修改之後先試著輸出一次:
class Competition{
#competitionName = 'hot pot';
#competitionDate
constructor(date){
this.#competitionDate = date;
}
}
console.log(hotpotCompetition.competitionName);//undefined
console.log(hotpotCompetition.#competitionName);////SyntaxError