zoukankan      html  css  js  c++  java
  • 10、TypeScript中的装饰器

    装饰器:装饰器是一种特殊的声明,他能够被附加到类声明方法、属性或参数上,可以修改类的行为。
    通俗的讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、方法、参数的功能。
    常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器
    装饰器的写法:普通装饰器(无法传参)、装饰器工厂(可以传参)。
    装饰器是过去几年中js最大的成就之一。已是Es7的标准特性之一。
    1、类装饰器:类装饰器在类声明前被声明(紧靠着类声明)。类装饰器应用于类构造函数,可以用来监视、修改或替换类定义。传入一个参数
    1-1、普通类装饰器(无法传参)
    function logClass(params:any){
      console.log(params);
      // params就是当前类
      params.prototype.apiUrl = '动态扩展的属性';
      params.prototype.run = function(){
        console.log('动态扩展的run方法')
      }
    }
    
    @logClass
    class HttpClient{
      constructor(){}
      getData(){}
    }
    var httpUrl:any = new HttpClient();
    console.log(httpUrl.apiUrl)
    httpUrl.run()
    1-2、类装饰器:装饰器工厂(可传参)
    function logClass(params:string){
      return function(target:any){
        console.log(params)
        console.log(target)
        target.prototype.apiUrl = params;
      }
    }
    
    @logClass('http://www.baidu.com/api')
    class HttpClient{
      constructor(){}
      getData(){}
    }
    var httpUrl:any = new HttpClient();
    console.log(httpUrl.apiUrl)

    支持多个装饰器

    如果有多个装饰器,会先执行后面的

    @logClass1('aaa') // 后

    @logClass2('bbb') // 先

    class HttpClient {}

    构造函数重载

      下面是一个重载构造函数的列子。
      类装饰器表达式会在运行时当做函数被调用,类的构造函数作为唯一的参数。
      如果类装饰器返回一个值,他会使用提供的构造函数来替换类的声明
    function logClass (target:any) {
        return class extends target {
            apiUrl:any = '我是修改后的构造函数 apiUrl'
            getData () {
                console.log(this.apiUrl + ' - next')
            }
        }
    }
    
    @logClass
    class HttpClient {
        public apiUrl:string | undefined;
        constructor() {
            this.apiUrl = '我是构造函数 apiUrl'
        }
        getData() {
            console.log(this.apiUrl)
        }
    }
    
    var http = new HttpClient()
    http.getData()
    2、属性装饰器
      属性装饰器表达式会在运行时当做函数被调用,传入下列2个参数;
        1、对于静态成员来说是类的构造函数,对于实力成员是类的原型对象。
        2、成员名字。
    function logProperty(params:string) {
        return function (target:any, attr:any) {
            // target 是类的原型对象, attr 属性的名称 (url)
            target[attr] = params
        }
    }
    
    @logClass('/api/demo')
    class HttpClient {
        @logProperty('http://www.baidu.com')
        public url:any | undefined;
        constructor() {}
        getData() {
            console.log(this.url)
        }
    }
    
    var http:any = new HttpClient()
    console.log(http.apiUrl)
    3、方法装饰器
      他不被应用到方法的属性描述上,可以用来监视、修改或替换方法定义。

      方法装饰器会在运行时传入一下3个参数:
        1、对于静态成员来说是类的构造函数,对于实力成员是类的原型对象。
        2、成员的名字。
        3、成员的属性描述符。
    方法装饰器一
    function logMethods(params:any) {
      return function(target:any,methodsName:any,desc:any){
        console.log(target)
        console.log(methodsName)
        console.log(desc)
    
        target.apiUrl = 'sssssssss';
        target.run=function(){
          console.log('run')
        }
      }
    }
    
    class HttpClient{
      public apiUrl:string | undefined;
      constructor(){
        
      }
      @logMethods('http://www.baidu.com/api')
      getData(){
        
      }
    }
    
    var http:any = new HttpClient();
    console.log(http.apiUrl)
    http.run()
    方法装饰器二
    function get(params:any) {
      return function(target:any,methodsName:any,desc:any){
        console.log(target)
        console.log(methodsName)
        console.log(desc)
    
        // 修改装饰器的方法 把装饰器方法里面传入的所有参数改为string类型
        // 1、保存当前的方法
        var oMethods=desc.value;
        desc.value=function(...args:any[]){
          args=args.map((value)=>{
            return String(value)
          })
          oMethods.apply(this,args)
        }
      }
    }
    
    class HttpClient{
      public apiUrl:string | undefined;
      constructor(){
        
      }
      @get('http://www.baidu.com/api')
      getData(...args:any[]){
        console.log(args);
        console.log('我是getData中的方法');
      }
    }
    
    var http:any = new HttpClient();
    http.getData(123,'xxxxx')
    4、方法参数装饰器
      参数装饰器表达式会在运行时当做函数被调用,可以使用参数装饰器为类的原型添加一些元素数据,参入一下三个参数;
        1、对于静态成员来说是类的构造函数,对于实力成员是类的原型对象。
        2、参数的名字。
        3、参数在函数参数列表中的索引。
    function logParams(params:any) {
      return function(target:any,paramsName:any,paramsIndex:any){
        console.log(params)//rrrrrr
        console.log(target)//{getData: ƒ, constructor: ƒ}
        console.log(paramsName)//getData
        console.log(paramsIndex)//0
    
        target.apiUrl = params
      }
    }
    
    class HttpClient{
      public apiUrl:string | undefined;
      constructor(){
      }
      getData(@logParams('rrrrrr') uuid:any){
        console.log(uuid)//eee
        console.log('俺是getData里面的方法');
      }
    }
    
    var http = new HttpClient()
    http.getData('eee')
    console.log(http.apiUrl)//rrrrrr
      属性》方法》方法参数》类
      如果有多个同样的装饰器,他会先执行后面的。
  • 相关阅读:
    LCA——最近公共祖先
    P1576 最小花费
    CollaQ复现
    人体姿态估计Alphapose安装
    mingw安装
    MADDPG实现
    MFMARL(Mean Field Multi-Agent Reinforcement Learning)实现
    MASK_RCNN实现
    Insightface实现
    .tar.002文件怎么解压
  • 原文地址:https://www.cnblogs.com/wenshaochang123/p/13558609.html
Copyright © 2011-2022 走看看