装饰器是一种特殊类型的声明,它能够被附加到类声明方法, 访问符属性参数上。 装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。

TypeScript中装饰器还属于实验性语法,所以要想使用必须在配置文件中tsconfig.json编译选项中开启:

1 {
2   "compilerOptions": {
3      "experimentalDecorators": true,
4      "emitDecoratorMetadata": true, 
5   }
6 }    

类装饰器在类声明之前被声明(紧靠着类声明)。 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。

 1 function TestDectorator(constructor:any){
 2     constructor.prototype.getName=function(){
 3         console.log('小白')
 4     }
 5 }
 6 @TestDectorator
 7 class Test{
 8 }
 9 const test=new Test();
10 (test as any).getName()//小白

通过不同参数参数返回不同数据

 1 function TestDectorator(flag:boolean){
 2     if(flag){
 3         return function(constructor:any){
 4             constructor.prototype.getName=()=>{
 5                 console.log('小白')
 6             }
 7         }
 8     }else{
 9         return function(constructor:any){
10             constructor.prototype.getName=()=>{
11                 constructor.log('小黑')
12             }
13         }
14     }
15 }
16 @TestDectorator(true)
17 class Test{
18 }
19 const test=new Test();
20 (test as any).getName()//小白

重构

 1 function TestDectorator(){
 2     return function<T extends new (...args:any[])=>any> (constructor:T){
 3         return class extends constructor{
 4             name='小白'
 5             getName(){
 6                 return this.name
 7             }
 8         }
 9     }
10 }
11 const Test=TestDectorator()(class {
12     name:string;
13     constructor(name:string){
14         this.name=name
15     }
16 })
17 const test=new Test('小黑')
18 console.log(test.getName())//小白

方法装饰器声明在一个方法的声明之前(紧靠着方法声明)。 它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义

 1 function getNameDectorator(target:any,protertyKey:string,descriptor: PropertyDescriptor){
 2     console.log(target,1,protertyKey,2,descriptor)
 3     descriptor.value=function(){
 4         return '小白'
 5     }
 6 }
 7 class Test{
 8     name:string;
 9     constructor(name:string){
10         this.name=name
11     }
12     @getNameDectorator
13     getName(){
14         return this.name
15     }
16 }
17 const test=new Test('小黑')
18 console.log(test.getName())//小白

访问器装饰器声明在一个访问器的声明之前(紧靠着访问器声明)。 访问器装饰器应用于访问器的 属性描述符并且可以用来监视,修改或替换一个访问器的定义。

 1 function TestDectorator(target:any,protertyKey:string,descriptor: PropertyDescriptor){
 2    // descriptor.writable = false;
 3 }
 4 class Test{
 5     private _name:string;
 6     constructor(name:string){
 7         this._name=name
 8     }
 9     get name(){
10         return this._name
11     }
12     @TestDectorator
13     set name(name:string){
14         this._name=name
15     }
16 }
17 const test=new Test('小白')
18 test.name='小黑'
19 console.log(test.name)//小黑

属性装饰器声明在一个属性声明之前(紧靠着属性声明)

 1 function nameDectorator(target: any, propertyKey: string):any{
 2     const descriptor: PropertyDescriptor = {
 3             writable: false//不可修改
 4           };
 5     return descriptor
 6 }
 7 class Test{
 8     @nameDectorator
 9     name='小白'
10 }
11 const test=new Test()
12 test.name='小黑'//上面设置不能修改后,编译会报错
13 console.log()

参数装饰器声明在一个参数声明之前(紧靠着参数声明)。 参数装饰器应用于类构造函数或方法声明。

 1 function TestDecorator(target: any, method: string, paramIndex: number) {
 2     console.log(target, method, paramIndex);
 3     // 原型,方法名,参数所在的位置
 4   }
 5   
 6   class Test {
 7     getInfo(name: string, @TestDecorator age: number) {
 8       console.log(name, age);
 9     }
10   }
11   
12   const test = new Test();
13   test.getInfo('小白', 18);

一个实例

 1 const userInfo:any=undefined
 2 function TestDecorator(mes:string){
 3     return  function (target:any,protertyKey:string,descriptor: PropertyDescriptor){
 4         const fn=descriptor.value//把函数保存起来
 5         descriptor.value=function(){
 6             try{
 7                 fn()
 8             }catch{
 9                 console.log(mes)
10             }
11         }
12      }
13 }
14 
15 class Test{
16     @TestDecorator('userInfo.name找不到')
17     getName(){
18          return userInfo.name
19     }
20     @TestDecorator('userInfo.age找不到')
21     getAge(){
22         return userInfo.age
23     }
24 }
25 const test=new Test()
26 test.getName()//userInfo.name找不到
27 test.getAge()//userInfo.age找不到

 

posted on 2020-06-22 17:45  小白学前端  阅读(230)  评论(0编辑  收藏  举报