TypeScript学习(七)装饰器(完结)

装饰器

定义:装饰器是一个方法,可以注入到类、方法、属性参数上类扩展、属性、方法、参数的功能

1.类装饰器
普通饰器

不能传参数

// 定义一个装饰器
function logClass(param:any){
    console.log(param)//输出:ƒ HttpClient() {}
    // 扩展类的属性与方法
    param.prototype.apiUrl="xxx"
    param.prototype.run=function(){
        console.log("动态扩展的run方法")
    }
}
@logClass
class HttpClient{
    constructor(){}
    getData(){

    }
}
let h:any = new HttpClient()
h.run()//动态扩展的run方法
装饰器工厂

可以传参

// 定义一个装饰器工厂
// param接收自己传的参数
// target接收类信息
function logClass(param:string){
    return function(target:any){
        console.log(param,target)//xxx ƒ HttpClient() {}
        // 属性扩展
        target.prototype.url = param
    }
}

@logClass("xxx")
class HttpClient{
    constructor(){}
    getData(){

    }
}

let h:any = new HttpClient()
console.log(h.url)//xxx

使用装饰器重载类方法

// 定义一个装饰器类重载方法
function logClass(param:any){
    return class extends param{
        api:any="修饰器修改的api"
        getData(){
            console.log("装饰器重载的方法")
        }
    }
}

@logClass
class HttpClient{
    api:string
    constructor(){
        this.api="构造函数的api"
    }
    getData(){

    }
}

let h:any = new HttpClient()
h.getData()//装饰器重载的方法
console.log(h.api)//修饰器修改的api
2.属性装饰器

接收两个参数

// 属性装饰器
// target接收类的原型对象
// param接收自己传入参数值
// attr接收修饰的属性名称
function logProps(param:any){
    return (target:any,attr:any)=>{
        console.log(param,target,attr)//xxx {getData: ƒ, constructor: ƒ} api
        // 修改属性
        target[attr]=param
    }
} 
// @logClass
class HttpClient{
    @logProps("xxx")
    api:string|undefined
    constructor(){
        
    }
    getData(){
        console.log(this.api)
    }
}

let h:any = new HttpClient()
h.getData()//xxx
3.方法装饰器
// 方法装饰器
// param:传入参数
// target:被修饰的是静态成员,则是类的构造函数
        // 被修饰的是实例成员,则是类的原型对象
// methodName:被修饰方法的方法名
// des:成员的属性描述符(des.value是当前方法)
function logMethod(param:any){
    return function(target:any,methodName:string,des:any){
        console.log(param,target,methodName,des)
        // 扩展属性
        target.url="xxsss"
        // 扩展方法
        target.run=function(){
            console.log("这是扩展的方法")
        }
        // 修改装饰器的方法
        // 1.保存当前方法
        let md = des.value
        //将原方法的参数替换为string类型
        des.value = function(...args:any[]){
            args=args.map((item)=>String(item))
            console.log(args)
            // 对象冒充,来修改方法,若不写,则将会替换原方法
            md.apply(this,args)
        }
    }
}
class HttpClient{
   
    api:string|undefined
    constructor(){
        
    }
    @logMethod("xxxx")
    getData(){
        console.log(this.api)
    }
}

let h:any = new HttpClient()
h.run()//这是扩展的方法
console.log(h.url)//xxsss
h.getData(123,665)
4.方法参数装饰器
// 方法参数装饰器
// 在执行方法时,调用方法参数装饰器,给类的原型对象增加属性,也可以修改参数
// param:传入参数
// target:被修饰的是静态成员,则是类的构造函数
        // 被修饰的是实例成员,则是类的原型对象
// methodName:被修饰方法的方法名
// paramIndex:参数索引下标
function logParams(param:any){
    return function(target:any,methodName:any,paramIndex:any){
        console.log(param,target,methodName,paramIndex)
         // 给原型对象增加属性
         target.id=param
    }
}

class HttpClient{
    url:string|undefined
    get(@logParams("uuid")uuid:any){
        console.log("类里面的实例方法"+uuid)
       
    }
}
let h:any = new HttpClient()
h.get(12233)//类里面的实例方法12233
console.log(h.id)//uuid

总结

装饰器可以对类、方法、属性、参数进行修改、扩展、替换等操作

执行顺序:属性装饰器->方法装饰器->方法参数装饰器->类装饰器

同类装饰器执行顺序:由下向上、由里及外、由后往前

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值