一文掌握ts中的装饰器(注解)

本文详细介绍了 TypeScript 中的装饰器使用,包括类装饰器的无参和传参写法、装饰器工厂、重载构造函数,以及属性、方法和参数装饰器的实现与应用。通过实例展示了如何利用装饰器扩展类的功能,修改方法和参数,增强了代码的可扩展性和维护性。
摘要由CSDN通过智能技术生成

类装饰器

  • 类装饰器:在类声明之前被声明,紧靠着类声明。应用于类构造函数,用来监视、修改、替换类定义传入一个参数 用来扩展类的属性、方法。
    类装饰器有两种应用方法,一种是传入参数的,一种是不传的。

无参写法

function logClass(params:any){
    console.log(params) // 这个patams 就是当前的类
    // 因此我们可以操作这个类
    params.prototype.apiUrl = 'xxx'

    params.prototype.run = function(){
        console.log('用装饰器给类添加的方法')
    }
}

@logClass
class HttpClient{
    constructor(){

    }
    getData(){}
}
 var http:any = new HttpClient();
 console.log(http.apiUrl) // xxx
 http.run() // 用装饰器给类添加的方法

传参写法(装饰器工厂)

 function logClass2(params:string){
     return function(target:any){ // 返回的target就是调用本装饰器的类
         console.log(target)
         console.log(params)

         target.prototype.apiUrl = params; // 将传入的参数赋值给该类的原型扩展属性apiUrl
     }
 }

 @logClass2('www.baidu.com') // 调用装饰器同时传入一个string类型的参数
 class HttpClient2{
    constructor(){

    }
    getData(){}
}
var http:any = new HttpClient2();
console.log(http.apiUrl) // www.baidu.com

类装饰器重载构造函数

  • 类装饰器重载构造函数可以增强可扩展性,功能增加,不修改核心代码也能进行扩展修改。
function logClass3(target:any){
    console.log(target); // 调用装饰器的类
    return class extends target{ // 返回一个target的继承,进行一个扩展
        apiYrl:any = '这是修改后的数据'
        getData(){
            this.apiYrl = this.apiYrl+'----';
            console.log(this.apiYrl) // 我是构造函数里的apiYrl----
        }
    }
}

@logClass3
class HttpClient3{
    public apiYrl:string | undefined;
    constructor(){
        this.apiYrl = '我是构造函数里的apiYrl'
    }
    getData(){
        console.log(this.apiYrl) // 我是构造函数里的apiYrl
    }
}// 在实例化同时传入值并且被打印出来
var hc3 = new HttpClient3()
http.getData()

属性装饰器

  • 属性装饰器回在运行时被当作函数来调用,传入两个参数:
    1.对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
    2.成员的名字
function logProperty(params:any){
    return function(target:any,attr:any){
        console.log(target)
        console.log(attr)
        // 把传进来的参数赋值到实例中 
        target[attr] = params; // s:'www.baidu.com's:'www.baidu.com'
    }
}
class HttpClient4{
    @logProperty('www.baidu.com,%s')
    public url:any | undefined; // 可以给我们的属性赋值
    constructor(){

    }
    getData(){
        console.log(this.url)
    }
}
var http:any = new HttpClient4()
http.getData()

方法装饰器

  • 它会被应用到方法的属性描述符上,可以用来监视 修改 替换 方法定义。
    方法装饰器运行时传入3个参数:
    1.对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象
    2.成员的名字
    3.成员的属性描述符
function logMethod(params:any){
    return function(target:any,methodName:any,desc:any){
        console.log(target);
        console.log(methodName);
        console.log(desc);

        target.apiUrl = params
        target.run = function(){
            console.log('run')
        }
    }
}
class HttpClient6{
    public url:any | undefined;
    constructor(){

    }
    @logMethod('www.baidu.com')
    getData(){
        console.log(this.url)
    }
}
var http:any = new HttpClient6()
console.log(http.apiUrl)
http.run()

使用方法装饰器修改方法

function logMethod2(params:any){
        return function(target:any,methodName:any,desc:any){
            console.log(target); 
            console.log(methodName);
            console.log(desc);
            console.log(desc.value);

            // !修改装饰器的方法,把装饰器所有传入的参数改为string
            // 1. 保存当前的方法
            var oMethod = desc.value;
            desc.value = function(...args:any[]){
                args = args.map((value)=>{ // map 循环遍历
                    return String(value) // 转类型
                })

                console.log(args) // [ 123, 999 ]

                oMethod.apply(this.args) // 用对象冒充来实现 把当前方法和参数传入
            }

        }
    }
    class HttpClient7{
        public url:any | undefined;
        constructor(){
    
        }
        @logMethod('www.baidu.com')
        getData(...args:any){ // 将传入的any类型的参数解构
            console.log(args)
            console.log("我是getData里的方法")
            console.log(this.url)
        }
    }
    var http = new HttpClient7()
    http.getData(123,999)

(方法)参数装饰器

  • 会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据,传入下列3个参数
    1.对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象
    2.参数的名字
    3.参数在函数参数列表中的索引
function logparams(params:any){
       return function(target:any,methodName:any,paramsIndex:any){
           console.log(params) // 传入的参数
           console.log(target) // 当前传入类的原型对象
           console.log(methodName) // 传入的方法名
           console.log(paramsIndex) // 索引值

           // 给这个参数添加传入的值
           target.apiUrl = params;
       }
   }

   class HttpClient8{
    public url:any | undefined;
    constructor(){

    }
    getData(@logparams('xxxx') uuid:any){ // 在方法的参数里面调用装饰器,传入参数,在参数里还需要接收这个参数
        console.log("我是getData里的方法")
    }
}
var http = new HttpClient8()

http.getData(123123);
console.log(http.apiUrl) // xxxx
  • 装饰器的执行顺序:属性装饰器 =》方法装饰器从后向前 =》类装饰器从后向前
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值