前言
傳統(tǒng)的JavaScript中漾稀,使用的是基于原型的繼承方式來使用類躲庄,雖然在ES6中明確提出了類關(guān)鍵字涧郊,但是支持度還不高预愤。TypeScript允許你直接使用ES6的類語法沟于,并且實現(xiàn)了各大瀏覽器和平臺的支持。
一植康、基本使用
class Person {
name: string
constructor(name: string) {
this.name = name;
}
}
然后這樣使用這個類:
let mss = new Person("mss");
console.log(mss.name);
// mms
二旷太、類的繼承
定義基礎(chǔ)類
class Animal {
name: string
constructor(name: string) {
this.name = name;
}
move(speed: number = 0) {
console.log(`${this.name}移動了${speed}`);
}
}
定義繼承類,并且使用繼承類重寫基礎(chǔ)類的方法
class Cat extends Animal {
constructor(name: string) {
super(name)
}
move(speed: number = 10) {
super.move(speed);
}
}
然后你這樣使用繼承類:
let cat = new Cat("??");
cat.move(20);
// ??移動了20
上面的例子就是很簡單的使用extends
實現(xiàn)類繼承的例子销睁,我們在繼承類的內(nèi)部使用super
關(guān)鍵字改寫了基礎(chǔ)類的move
方法供璧。
三冻记、Public, private, and protected
在其他的強類型語言中演顾,有public
等關(guān)鍵字標(biāo)記變量的使用范圍邀层,TypeScript中也提供了這些關(guān)鍵字摄悯。
1.public
public
關(guān)鍵字是標(biāo)記變量或者方法是公用的,不管在父類和子類都能使用。在TypeScript中默認(rèn)就是public
,也就是當(dāng)你沒有使用任何范圍關(guān)鍵字修飾豁跑,默認(rèn)就是公用的變量和方法宠纯,當(dāng)然你也可以顯示的使用puclic
聲明快集。
class aAnimal {
public name: string
public constructor(name:string) {
this.name = name;
}
public move(speed: number) {
console.log(speed);
}
}
然后可以定義繼承類:
class Dog extends aAnimal {
constructor(name: string) {
super(name);
}
}
我們可以在基礎(chǔ)類和繼承類中都可以訪問到name
屬性:
// 基礎(chǔ)類可以訪問
console.log(aAnimal.name);
// 繼承類也可以訪問
let dog = new Dog("mss");
console.log(dog.name);
// mss
2.private
private
是用來標(biāo)記一個類中私有變量的關(guān)鍵字蒙秒,一旦使用private
標(biāo)記覆获,表示申明了該變量是類私有的,只能在類中進行訪問涤伐。
基礎(chǔ)類
class sAnimal {
private name: string;
constructor(theName: string) {
this.name = theName;
}
}
繼承類:
class Snake extends sAnimal {
constructor(name: string) {
super(name);
}
}
然后試著去訪問繼承類中的name
屬性:
class Snake extends sAnimal {
constructor(name: string) {
super(name);
// 這里訪問基礎(chǔ)類的name屬性
console .log(super.name);
}
}
發(fā)現(xiàn)都不能訪問器净,也應(yīng)證了確實只能在基礎(chǔ)類類中進行訪問。
3.protected
protected
關(guān)鍵字標(biāo)記的變量在基礎(chǔ)類的子類和衍生類中都能訪問。比如把上面的例子中provate
改為protected
:
class sAnimal {
protected name: string;
constructor(theName: string) {
this.name = theName;
}
}
class Snake extends sAnimal {
constructor(name: string) {
super(name);
// 這里可以正常訪問
console .log(super.name);
}
}
3.readonly
readonly
關(guān)鍵字用來修飾只讀屬性
class OtherPerson {
readonly name: string;
constructor(name: string) {
this.name = name;
}
}
let me = new OtherPerson("mss");
// me.name = ''
當(dāng)我們試圖設(shè)置me
實例的name
屬性時佛掖,TypeScript會報錯坐榆,因為我們使用了readonly
關(guān)鍵字描述了只讀屬性。
同時,TypeScript也允許在申明的時候同時初始化參數(shù):
class OtherPerson {
readonly age: number = 18
constructor(readonly name: string) {
console.log(name);
}
}
let me = new OtherPerson("mss");
// me.name = ''
這樣做也是合理的,其他如public
等修飾符也可以在聲明變量的同時初始化,用法和這個例子是一致的缺厉。
四永高、訪問器屬性
和JavaScript中一樣,TypeScrip中也提供了訪問器屬性提针,使得開發(fā)者可以對對象進行更細粒度的控制乏梁。值得注意的是,一旦在對象中設(shè)置了get
和set
方法关贵,TypeScript會默認(rèn)用readonly
修飾set
和get
方法遇骑。
我們可以利用訪問器屬性,實現(xiàn)對一個輸入的字符串的校驗,我們首先設(shè)置了輸入的長度為10位:
const maxLength = 10;
然后我們?yōu)轭惗xget
和set
訪問器方法:
lass ValidName {
private name: string = "";
get fullName () {
return this.name;
}
set fullName (newName: string) {
if (newName && newName.length > maxLength) {
throw new Error("輸入的字符串不合法揖曾!");
}
this.name = name;
}
}
當(dāng)我們傳入的字符串不符合長度的時候落萎,會給我們一個友好的提示。同時炭剪,注意练链,訪問起屬性只能在編譯器是ES5+的版本才能使用。
五奴拦、靜態(tài)類
前面我們提到可以使用修飾符對類中的變量進行訪問范圍的控制媒鼓,靜態(tài)屬性修飾符的作用也是在于此,使用static
修飾符修飾變量错妖,可以使得該變量只能被該類直接訪問绿鸣。
class StaticObj {
static age: number = 18;
getAge() {
return StaticObj.age;
}
}
然后我們訪問age
屬性的時候,只能通過StaticObj
簽名進行訪問:
console.log(StaticObj.age);
// 18
六暂氯、抽象類
抽象類的行為可以有這樣幾個特點:
- 抽象類不能實例化潮模,只能作為基礎(chǔ)類供其他類繼承。
- 使用
abstract
關(guān)鍵字定義抽象類和抽象方法痴施,抽象方法只包括定義擎厢,不包括實現(xiàn)。- 基于抽象類的衍生類必須實現(xiàn)抽象類的抽象方法辣吃。
我們首先定義一個抽象類和抽象方法动遭,注意抽象方法必須是在抽象類中定義:
abstract class AbstractObj {
abstract getName(): void
}
然后定一個AbstractObj
抽象類的繼承類ImpleAbstractObj
class ImpleAbstractObj extends AbstractObj{
public name: string = 'mss'
public age: number = 18
// 這里實現(xiàn)了抽象類的getName方法
getName(): void {
console.log(this.name);
}
getAge() {
return this.age;
}
}
七、類可以當(dāng)作接口使用
前面說到了接口
是TypeScript定義數(shù)據(jù)結(jié)合類型的一個虛擬結(jié)構(gòu)神得,對于類來說厘惦,也可以當(dāng)作接口
的功能。
你可以像使用接口
一樣使用類
class baseObj {
name: string
}
同等功能的接口是這樣定義:
interface baseObj {
name: string
}
然后這樣使用:
let irObj: baseObj = {
name: 'mss'
}
八循头、總結(jié)
ES6之前JavaScript并沒有正式的關(guān)于類的概念绵估,ES6之后新增了class
的關(guān)鍵字炎疆,雖然只是基與ES5原型的語法糖,但是也算是方便了前端開發(fā)者国裳。同時,TypeScript中引入了強類型語言中類的特性形入,使得JS向開發(fā)大型的項目又跨進了一步。