什么是裝飾器
裝飾器是一種特殊類型的聲明,它能夠被附加到類聲明,方法,訪問符,屬性或參數上,是一種在不改變原來類和使用繼承的情況下,動態擴展對象功能。
同樣,本質也不是什么高大上的結構,就是一個普通的函數,expression
的形式其實是Object.defineProperty
的語法糖
expression
求值后必須也是一個函數,它會運行時被調用,被裝飾的聲明信息作為參數傳入
使用方式
在ts里,要是會用,需要在tsconfig.json文件啟動
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
類裝飾
聲明一個函數addAge
去給Class的屬性 age
添加年齡
function addAge(constructor:Function){
constructor.prototype.age = 18
}
@addAge
class Person{
name:string;
age!:number;
constructor(){
this.name = '張三'
}
}
let person = new Person();
console.log(person.age) //18
方法/屬性裝飾
參數裝飾
訪問器裝飾
裝飾器工廠
執行順序
當多個裝飾器應用于一個聲明上,將由上至下依次對裝飾器表達式求值,求值的結果會被當作函數,由下至上依次調用,例如如下:
function f() {
console.log("f(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("f(): called");
}
}
function g() {
console.log("g(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("g(): called");
}
}
class C {
@f()
@g()
method() {}
}
// 輸出
f(): evaluated
g(): evaluated
g(): called
f(): called
應用場景
可以看到,使用裝飾器存在兩個顯著的優點:
- 代碼可讀性變強了,裝飾器命名相當于一個注釋
- 在不改變原有代碼情況下,對原來功能進行擴展
后面的使用場景中,借助裝飾器的特性,除了提高可讀性之后,針對已經存在的類,可以通過裝飾器的特性,在不改變原有代碼情況下,對原來功能進行擴展