09 装饰器定义 类装饰器 属性装饰器 装饰器工厂

装饰器

装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为。

通俗的讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。

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

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

装饰器是过去几年中js最大的成就之一,已是es7的标准特性之一 。

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

    • 类装饰器:普通装饰器(不可传参)
    function logClass(params:any){
        console.log(params);
        // params就是当前类
        params.prototype.apiUrl='xxxxx';
        params.prototype.run=function(){
            console.log('我是一个run方法');        
        }
    }
    
    @logClass
    class HttpClient {
        constructor() {
        }
        getData(){
        }
    }
    let http=new HttpClient();
    console.log(http.apiUrl);
    http.run();
    
    • 装饰器:装饰器工厂(可传参)
    function logClass(params:string){
       return function(target:any){
           console.log(target);
           console.log(params);    
           target.prototype.apiUrl=params;      
       }
    }
    @logClass('http://www.baidu.com')
    class HttpClient{
       constructor(){
       }
       getData(){
       }
    }
    let http=new HttpClient();
    console.log(http.apiUrl);
    

类装饰器表达式会在运行时当做函数被调用,类的构造函数作为其唯一的参数。

如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。

下面是一个重载构造函数的例子。

function logClass(target: any) {
    // console.log(target);
    return class extends target {
        apiUrl = '我是修改后的数据';
        getData(){
            console.log(this.apiUrl+'-----');            
        }
    }
}
@logClass
class HttpClient {
    apiUrl: string | undefined;
    constructor() {
        this.apiUrl = '我是构造函数里面的apiUrl';
    }
    getData() {
        console.log(this.apiUrl);
    }
}
let http = new HttpClient();
http.getData(); 
  1. 属性装饰器

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

    • 对于静态成员说是类的构造函数,对于实例成语是类的原型对象。
    • 属性的名字。
    function logProperty(params: any) {
        return function (target: any, attr: any) {
            console.log(target);
            console.log(attr);
            target.attr = params;
        }
    }
    @logClass('http://www.baidu.com')
    class HttpClient {
        @logProperty('http://www.qq.com')
        apiUrl: string | undefined;
        constructor() {
            this.apiUrl = '我是构造函数里面的apiUrl';
        }
        getData() {
            console.log(this.apiUrl);
        }
    }
    let http=new HttpClient();
    http.getData();
    
  2. 方法装饰器

    它会被应用到方法的属性描述符上,可以用来见识,修改或者替换方法的定义。

    方法装饰器会在运行传入下列3个参数:

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

    • 方法的名字。

    • 方法的属性描述符。

      方法装饰器(1)

      function get(params:any){
          return function(target:any,methodsName:any,desc:any){
              console.log(target);
              console.log(methodsName);
              console.log(desc);
      
              target.apiUrl='我是装饰器扩展的属性';
              target.run=function(){
                  console.log('我是装饰器扩展的方法'); 
              }
          }
      }
      class HttpClient {
          apiUrl: string | undefined;
          constructor() {        
          }
          @get('http://www.ti.com')
          getData() {
              console.log(this.apiUrl);
          }
      }
      let http=new HttpClient();
      console.log(http.apiUrl);
      http.run();
      

      方法装饰器(2)

      function get(params: any) {
        console.log(params);    
        return function (target: any, methodsName: any, desc: any) {
            console.log(target);
            console.log(methodsName);
            console.log(desc.value);
            // 修改装饰器的方法 把装饰器方法里面传入的所有参数改为string类型
            // 1.保存当前的方法
            let oMethod = desc.value;
            // 2.替换方法
            desc.value = function (...args: any[]) {
                args.map((value) => {
                    return String(value);
                });
                console.log(args);
                // 3.修改方法
                oMethod.apply(this, args);
            }
        }
      }
      class HttpClient {
        apiUrl: string | undefined;
        constructor() {
        }
        @get('http://www.ti.com')
        getData(...agrs:any[]) {
            console.log('我是getData里面的方法');
        }
      }
      let http = new HttpClient();
      http.getData(123, 'xxx');
      
  3. 方法参数装饰器

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

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

    • 方法的名称

    • 参数在函数参数列表中的索引

      function logParams(params: any) {
          console.log(params);    
          return function (target: any, methodName: any, paramsIndex: any) {
              console.log(target);
              console.log(methodName);
              console.log(paramsIndex);
      
              target.url=params;
          }
      }
      class HttpClient {
          [x: string]: any;
          apiUrl: string | undefined;
          constructor() {
          }
          getData(@logParams('xxxxx') uuid: any) {
              console.log(uuid);
          }
      }
      let http=new HttpClient();
      http.getData('123456');
      console.log(http.url);
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值