2020年11月12日

ts-装饰器

作者 rourou

/装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为。通俗点讲就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。

常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器

装饰器写法:普通装饰器(无法传参数)、装饰器工厂(可传参)

  • 类装饰器:类装饰器在类声明之前被声明(紧跟类声明)。类装饰器应用于类构造函数,来监视,修改或替换类定义。
// 无传参
function logClass(p:any){
  // p是当前类
  console.log(p)//[Function: httpClient]
  p.prototype.api = 'xxx';//扩展属性
  p.prototype.run = function(){
    console.log('扩展方法');
  }
}
@logClass
class httpClient{
  constructor(){

  }
  getData(){

  }
}

var http:any = new httpClient();
console.log(http.api);//xxx
http.run();//扩展方法


// 有传参
function logClasss(p:any){
  return function(a:any){
    console.log(a)//[Function: httpClient1]
     console.log(p)//有参数
  }
}
@logClasss('有参数')
class httpClient1{
  api:string | undefined;
  constructor(){
    this.api = '复制'
  }
  getData(){
    console.log(this.api)//复制
  }
}

var httpClients = new httpClient1();
  • 类装饰器:装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。如果类装饰器返回一个值,会使用提供的够着函数来替换类的声明
function logClass2(p:any){
  return class extends p{
    api = '修改后'
    getData(){
      // console.log(this.api);
    }
  }
}
@logClass2
class httpClient3{
  api:string | undefined;
  constructor(){
    this.api = '复制';
  }
  getData(){
    // console.log(this.api);
  }
}

var httpClient2 = new httpClient3();
httpClient2.getData();//修改后
  • 属性装饰器:表达式会在运行时当作函数被调用,传入下列2个参数

1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象

2、成员名称

function logClasss4(p:any){
  return function(a:any,attr:any){
    console.log(p);//有参数a
    console.log(a);//httpClient4 { getData: [Function] }
    console.log(attr);//api
    a[attr] = p
  }
}
class httpClient4{
  @logClasss4('有参数a')
  api:string | undefined;
  constructor(){
  }
  getData(){
    console.log(this.api)
  }
}

var httpClient5 = new httpClient4();
httpClient5.getData();//有参数a
  • 方法参数装饰器:表达式会在运行时当做函数被调用,可以使用参数装饰器为类的原型增加一些元素数据。

方法装饰器会在运行时传入下列3个参数:1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。2、方法名称3、参数在函数参数类表中索引

class Greeter {
    greeting: string;

    constructor(message: string) {
        this.greeting = message;
    }

    greet(@required name: string) {
        return "Hello " + name + ", " + this.greeting;
    }
}
  • 方法装饰器 :应用到方法的 属性描述符上,可以用来监视,修改或替换方法定义

方法装饰器会在运行时传入下列3个参数:1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象2、方法的名字3、成员的属性描述符(xx.value可以修改)

class Greeter {
    greeting: string;

    constructor(message: string) {
        this.greeting = message;
    }

    @validate
    greet(name: string) {
        return "Hello " + name + ", " + this.greeting;
    }
}