ECMAScript 6引入了class關(guān)鍵字以創(chuàng)建JavaScript中的類?,F(xiàn)在,你可以使用class屬性在JavaScript中創(chuàng)建類。在ECMA 6之前,無論何時(shí)使用new運(yùn)算符調(diào)用一個(gè)函數(shù),該函數(shù)都會(huì)返回一個(gè)新對(duì)象。因此,此函數(shù)是作為一個(gè)類來使用的,并被稱為構(gòu)造函數(shù)。這種調(diào)用函數(shù)來返回對(duì)象的方式也被稱為構(gòu)造函數(shù)調(diào)用模式。
但在ECMAScript 6中,可以使用class關(guān)鍵字創(chuàng)建類。請(qǐng)看下面的代碼:
class Car {
constructor(maker, price) {
this.maker = maker;
this.price = price;
}
getInfo() {
console.log(this.maker + " costs : " + this.price);
}
}
在上面的代碼片段中,你已經(jīng)使用ECMAScript 6 class關(guān)鍵字創(chuàng)建了一個(gè)名為Car的類。你也可以創(chuàng)建一個(gè)Car類的對(duì)象,如下所示:
var car1 = new Car("BMW", 100);
car1.getInfo();
var car2 = new Car("Audi", 150);
car2.getInfo();
JavaScript類是慣?;谠偷睦^承的簡化語法。它不提供任何新的對(duì)象創(chuàng)建或原型繼承方式,并且不會(huì)在JavaScript中引入任何面向?qū)ο蠡蚶^承的新模型。你也可以說類是創(chuàng)建對(duì)象的特殊函數(shù)。
類聲明和表達(dá)
由于JavaScript中的class屬性也是一個(gè)函數(shù),所以也可以使用類聲明和類表達(dá)式來創(chuàng)建。你可以使用類聲明創(chuàng)建一個(gè)類,如下所示:
class Car {
constructor(maker, price) {
this.maker = maker;
this.price = price;
}
getInfo() {
console.log(this.maker + " costs : " + this.price);
}
}
類也可以使用類表達(dá)式來創(chuàng)建。你可以創(chuàng)建命名或未命名的類表達(dá)式??梢赃@樣創(chuàng)建命名的類表達(dá)式,如下所示:
var Car = class {
constructor(maker, price) {
this.maker = maker;
this.price = price;
}
getInfo() {
console.log(this.maker + " costs : " + this.price);
}
toString() {
return `${this.maker} costs : ${this.price}`;
}
}
未命名的類表達(dá)式可以如下所示地被創(chuàng)建。給類表達(dá)式的名稱是類主體的本地名稱。
var Car = class c {
constructor(maker, price) {
this.maker = maker;
this.price = price;
}
getInfo() {
console.log(this.maker + " costs : " + this.price);
}
toString() {
return `${this.maker} costs : ${this.price}`;
}
}
類的提升
如前所述,一個(gè)類既可以作為聲明又可以作為表達(dá)式來創(chuàng)建,但是與函數(shù)聲明不同,類聲明不會(huì)被提升到執(zhí)行上下文的頂部。請(qǐng)看下面的代碼:
var car1 = new Car("BMW", 10); // Reference Error console.log(car1.toString());
class Car {
constructor(maker, price) {
this.maker = maker;
this.price = price;
}
getInfo() {
console.log(this.maker + " costs : " + this.price);
}
toString() {
return `${this.maker} costs : ${this.price}`;
}
}
上面的代碼會(huì)拋出引用錯(cuò)誤(Reference Error),因?yàn)槟阍诼暶魉霸噲D訪問一個(gè)類。因此,我們可以得到函數(shù)聲明被提升,而類聲明不被提升的結(jié)論。
類方法
JavaScript類中有三種類型的方法:
- 構(gòu)造方法。
- 靜態(tài)方法。
- 原型方法。
類構(gòu)造函數(shù)方法創(chuàng)建初始化對(duì)象。一個(gè)類只能有一個(gè)構(gòu)造方法。如果你嘗試創(chuàng)建多個(gè)構(gòu)造函數(shù)方法,則JavaScript將引發(fā)異常??梢允褂藐P(guān)鍵字constructor 創(chuàng)建構(gòu)造函數(shù),如下面的代碼所示:
class Car {
constructor(maker, price) {
this.maker = maker;
this.price = price;
}
}
JavaScript類的靜態(tài)方法是用類調(diào)用的,而不是用類的特定對(duì)象調(diào)用的。如果你嘗試用類的實(shí)例調(diào)用它們,則JavaScript將拋出異常。使用關(guān)鍵字static可以創(chuàng)建靜態(tài)方法,如下所示:
class Car {
static count() {
console.log("I am static method");
}
}
Car.count();
Car.count();
如果你試圖用實(shí)例調(diào)用靜態(tài)方法,那么JavaScript會(huì)拋出異常說明這個(gè)函數(shù)不存在。另外,請(qǐng)記住,JavaScript類沒有靜態(tài)屬性或成員。截至目前,它只支持靜態(tài)方法。
任何使用類實(shí)例訪問的常規(guī)方法都被稱為原型方法。這些方法可以繼承和使用類的對(duì)象。
class Car {
constructor(maker, price) {
this.maker = maker;
this.price = price;
}
getInfo() {
console.log(this.maker + " costs : " + this.price);
}
}
var car1 = new Car("BMW", 10);
car1.getInfo();
在上面的代碼片段中,getInfo()是Car類的原型方法。正如你所看到的,我們正在使用Car類的實(shí)例。由于它是原型方法,所以也可以繼承。讓我們來探討為什么這些方法被稱為原型方法。首先,考慮下面的代碼:
class Car {
constructor(maker, price) {
this.maker = maker;
this.price = price;
}
getInfo() {
console.log(this.maker + " costs : " + this.price);
}
}
console.log(typeof (Car)); // function
在這個(gè)代碼片段中,我們輸入了一個(gè)Car類的類型,也得到了一個(gè)函數(shù)的輸出。正如你所看到的,這個(gè)類只是一個(gè)函數(shù)類型,所以和其他函數(shù)一樣,它也有一個(gè)prototype屬性。這些常規(guī)的方法是類的原型對(duì)象的方法,因此它們被稱為原型方法。它們可以通過堅(jiān)持基于原型的繼承而被繼承。
除了這三種類型的方法之外,JavaScript也有一些叫g(shù)etter和setter的東西,你可以點(diǎn)此處了解。
結(jié)論
在這篇文章中,我們簡要介紹了ECMAScript 2015中引入的JavaScript類屬性。使用class關(guān)鍵字,我們可以創(chuàng)建一個(gè)類,但是請(qǐng)記住,這不是引入對(duì)象創(chuàng)建或繼承的新方法。相反,對(duì)于相同的對(duì)象和基于原型的繼承,這只是一個(gè)更簡單的語法。