深入Typescript--03-Typescript中的類(努力加餐飯)
阿新 • • 發佈:2022-05-06
Typescript中的類
一.TS中定義類
class Pointer{
x!:number; // 例項上的屬性必須先宣告
y!:number;
constructor(x:number,y?:number,...args:number[]){
this.x = x;
this.y = y as number;
}
}
let p = new Pointer(100,200);
- 例項上的屬性需要先宣告在使用,建構函式中的引數可以使用可選引數和剩餘引數
二.類中的修飾符
- public修飾符(誰都可以訪問到)
class Animal { public name!: string; // 不寫public預設也是公開的 public age!: number; constructor(name: string, age: number) { this.name = name; this.age = age; } } class Cat extends Animal { constructor(name: string, age: number) { super(name, age); console.log(this.name,this.age); // 子類訪問 } } let p = new Cat('Tom', 18); console.log(p.name,p.age); // 外層訪問 class Animal { constructor(public name: string, public age: number) { this.name = name; this.age = age; } }
-
我們可以通過引數屬性來簡化父類中的程式碼
-
protected修飾符 (自己和子類可以訪問到)
class Animal { constructor(protected name: string, protected age: number) { this.name = name; this.age = age; } } class Cat extends Animal { constructor(name: string, age: number) { super(name, age); console.log(this.name, this.age) } } let p = new Cat('Tom', 18); console.log(p.name,p.age);// 無法訪問
- private修飾符 (除了自己都訪問不到)
class Animal { constructor(private name: string, private age: number) { this.name = name; this.age = age; } } class Cat extends Animal { constructor(name: string, age: number) { super(name, age); console.log(this.name, this.age); // 無法訪問 } } let p = new Cat('Tom', 18); console.log(p.name,p.age);// 無法訪問
- readonly修飾符 (僅讀修飾符)
class Animal {
constructor(public readonly name: string, public age: number) {
this.name = name;
this.age = age;
}
changeName(name:string){
this.name = name; // 僅讀屬性只能在constructor中被賦值
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
}
}
let p = new Cat('Tom', 18);
p.changeName('Jerry');
三.靜態屬性和方法
class Animal {
static type = '哺乳動物'; // 靜態屬性
static getName() { // 靜態方法
return '動物類';
}
private _name: string = 'Tom';
get name() { // 屬性訪問器
return this._name;
}
set name(name: string) {
this._name = name;
}
}
let animal = new Animal();
console.log(animal.name);
- 靜態屬性和靜態方法是可以被子類所繼承的
四.Super屬性
class Animal {
say(message:string){
console.log(message);
}
static getType(){
return '動物'
}
}
class Cat extends Animal {
say(){ // 原型方法中的super指代的是父類的原型
super.say('貓貓叫');
}
static getType(){ // 靜態方法中的super指代的是父類
return super.getType()
}
}
let cat = new Cat();
console.log(Cat.getType())
五.類的裝飾器
- 簡單來說,就是給一個類,新增一些好用的方法,其他類也能用,寫到原型上面,參考5.1
- 或者是修飾類裡的一些屬性方法,搞通用的那種函式,用來修飾,節省程式碼,可參考5.2,5.3
- 還可以修飾函式的引數哇 5.4
- 裝飾器作用就是為了擴充套件類,擴充套件類中的屬性和方法
- 只能修飾類,不可以修飾函式,函式有變數提升的問題
- 裝飾器必須是一個函式
- 執行=洋蔥模型,先從外層執行,執行完後,從內層倒序執行,一層一層剝開,再一層一層執行
1.裝飾類
function addSay(target:any){
target.prototype.say = function(){console.log('say')}
}
@addSay
class Person {
say!:Function
}
let person = new Person
person.say();
- 裝飾類可以給類擴充套件功能,需要開啟experimentalDecorators:true
2.裝飾類中屬性
// target 是類的原型,,key 是需要修飾的屬性
function toUpperCase(target:any,key:string){
let value = target[key];
Object.defineProperty(target,key,{ // 原型定義屬性
get(){
return value.toUpperCase();
},
set(newValue){
value = newValue
}
})
}
function double(target: any, key: string) {
let value = target[key];
Object.defineProperty(target, key, {
get() {
return value * 2;
},
set(newValue) {value = newValue}
})
}
class Person {
@toUpperCase
name: string = 'JiangWen'
@double
static age: number = 10;
getName() {
return this.name;
}
}
let person = new Person();
console.log(person.getName(),Person.age)
- 裝飾屬性可以對屬性的內容進行改寫,裝飾的是例項屬性則target指向類的原型、裝飾的是靜態屬性則target執行類本身~
3.裝飾類中方法
// 設定某些方法屬性是否可用
function noEnum(target:any,key:string,descriptor:PropertyDescriptor){
console.log(descriptor)
descriptor.enumerable = false;
}
class Person {
@toUpperCase
name: string = 'JiangWen'
@double
static age: number = 10;
@noEnum
getName() {
return this.name;
}
}
let person = new Person();
console.log(person); // getName 不可列舉
4.裝飾引數
function addPrefix(target:any,key:string,paramIndex:number){
console.log(target,key,paramIndex); // Person.prototype getName 0
}
class Person {
@toUpperCase
name: string = 'JiangWen'
@double
static age: number = 10;
prefix!:string
@noEnum
getName(@addPrefix prefix:string) {
return this.name;
}
}
六.抽象類
- 抽象類無法被例項化,只能被繼承,抽象方法不能在抽象類中實現,只能在抽象類的具體子類中實現,而且必須實現。
- 定義型別時void表示函式的返回值為空
abstract class Animal{
name!:string;
abstract speak():void
}
class Cat extends Animal {
speak(){
console.log('貓貓叫');
}
}
class Dog extends Animal{
speak():string{
console.log('汪汪叫');
return 'wangwang'
}
}