TypeScript的装饰器

2020-12-11  本文已影响0人  _hider

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性和参数上,可以修改它所装饰对象的行为。换句话说就是装饰器可以注入到类,方法,属性参数上来扩展类,属性,方法,参数的功能。

常见的装饰器有:类装饰器,属性装饰器,方法装饰器和参数装饰器。从写法区分的话分普通装饰器(无法传参)和装饰器工厂(可传参)。

一、类装饰器

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

无法参数的普通装饰器

//类装饰器
function BaseUrl(params:any):void {
  params.prototype.baseUrl = "http://www.baidu.com";
  params.prototype.getResponse = function():void{
    console.log("hello world");
  };
};

//通过@加上装饰器的名字的形式给类添加装饰器
@BaseUrl
class Axios {
  constructor(){}
};

const Http = new Axios();
console.log(Http.baseUrl); //http://www.baidu.com
Http.getResponse(); //hello world

装饰器给类的原型添加baseUrl参数和getResponse方法,可以让Axios类默认绑定上装饰器里的属性和方法。

可传参的装饰器

//类装饰器
function BaseUrl(params:string) {
  return function(target:any):void{
    target.prototype.baseUrl = params;
    target.prototype.getResponse = function():void{
      console.log("hello world");
    };
  };
};

//通过@加上装饰器的名字的形式给类添加装饰器
@BaseUrl("http://www.baidu.com")
class Axios {
  constructor(){}
};

const Http = new Axios();
console.log(Http.baseUrl); //http://www.baidu.com
Http.getResponse(); //hello world

可重载的装饰器

可重载的装饰器可用于替换类原有的属性和方法。

//类装饰器
function BaseUrl(target:any) {
  return class extends target{
    apiUrl:string = "http://www.google.com";
  };
};

//通过@加上装饰器的名字的形式给类添加装饰器
@BaseUrl
class Axios {
  public apiUrl:string;
  constructor(){
    this.apiUrl = "http://www.baidu.com";
  }
};

const Http = new Axios();
console.log(Http.apiUrl); //http://www.google.com
二、属性装饰器

属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:

以下实现一个属性装饰器,作用就是给属性添加默认值。

//属性装饰器
function BaseUrl(params: any){
  return function (target: any, attr: any){
    console.log(target); // Axios: {} 
    console.log(attr); // apiUrl
    console.log(params); // http://www.baidu.com
    target[attr] = params;
  };
};

class Axios {
  //添加属性装饰器
  @BaseUrl("http://www.baidu.com") 
  public apiUrl: string | undefined;
  constructor() {}
  getData() {
    console.log(this.apiUrl);
  }
};

let request = new Axios();
request.getData(); // http://www.baidu.com
三、方法装饰器

方法装饰器会被应用到方法的属性描述符上,可以用来监视,修改或替换方法定义。方法装饰器定义的时候会传入以下三个参数:

function BaseUrl(params:any){
  return function(target:any,methodName:any,desc:any){
    console.log(params); //http://www.baidu.com
    console.log(target); //{constructor: ƒ, getData: ƒ}
    console.log(methodName); //getData
    console.log(desc); //{writable: true, enumerable: false, configurable: true, value: ƒ}
    target.apiUrl = params;
  }
};
class Axios {
  public apiUrl: string | undefined;
  constructor() {}
  //添加方法装饰器
  @BaseUrl("http://www.baidu.com") 
  getData() {
    console.log(this.apiUrl); //http://www.baidu.com
  }
};

let request = new Axios();
request.getData();
四、方法参数装饰器

参数装饰器表达式会在运行时当作函数调用,可以使用参数装饰器为类的原型增加一些元素数据,传入以下三个参数:

function logClass(params: string): any {
  return function(target: any, methodName: any, paramsIndex: any) {
    console.log(target); // {constructor: ƒ, getData: ƒ}
    console.log(methodName); // getData
    console.log(paramsIndex); // 0
    console.log(params); // 50
  };
}
class Http {
  public name: string | undefined;
  constructor() {}
  getData(@logClass("don") uuid: any): void {
    console.log(uuid);
  }
}
const h: any = new Http();
h.getData(50);
五、装饰器执行的顺序

属性装饰器——方法装饰器——方法参数装饰器——类装饰器。
如果有多个同样的装饰器,它会从后向前执行。

上一篇 下一篇

猜你喜欢

热点阅读