装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为
通俗的讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能
常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器
装饰器的写法:普通装饰器(无法传参)、装饰参数器工厂(可传参)
类装饰器
类装饰器在类声明之前被声明(紧靠着声明类型),类装饰器应用于类构造函数,可以用来监视,修改或替换类定义,
//定义一个装饰器 function loge(params:any){ console.log(params) //输出当前类 } @loge class box{ constructor(){ } get(){ } }
编译后的js文件
我们可以在这params的原型链上添加方法或者属性,也就是给当前类的原型链上添加一个方法或者属性
//定义一个装饰器 function loge(params:any){ console.log(params) params.prototype.url='***' } @loge //不能有分号,挨着定义的类 class box{ constructor(){ } get(){ } } var box1=new box() console.log(box1)
console.log(box1.url)
装饰器工厂
function login(params:string){ return function(target:any){ console.log(target) console.log(params) } } @login("hello") class fun{ constructor(){ } get(){ } }
编译后的js文件
@login("hello")中的hello赋值于params,函数fun赋值于target
此时可以在target的原型链上添加方法
function login(params:string){ return function(target:any){ target.prototype.url=params } } @login("hello") class fun{ constructor(){ } get(){ } } var a=new fun() console.log(a.url)
类装饰器表达式会在运行时当做函数被调用,类的构造函数作为其唯一的参数
如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明
function login(params:any){ console.log(params) } @login class fun{ api:string|undefined; constructor(){ this.api="我是fun中的api" } get(){ console.log(this.api) } } var a=new fun() a.get()
此时我们重载参数或者构造函数
比如我们现在可以在login中修改constructorapi的值
function login(params:any){ console.log(params) return class extends params{ api:any="我是修改的" get(){ console.log("我是修改的get") } } } @login class fun{ api:string|undefined; constructor(){ this.api="我是fun中的api" } get(){ console.log(this.api) } } var a=new fun() a.get()
属性装饰器
属性装饰器会在运行时当做函数调用,传入以下2个参数
//类装饰器 function login(params:any){ return function(target:any){ } } //属性装饰器 function log(params:any){ return function(target:any,attr:any){ } } @login("hello") class fun{ @log("word") api:string|undefined; constructor(){ this.api="我是fun中的api" } get(){ } } var a=new fun() a.get()
此时可以看到输出
attr就是属性的名称
target就是当前类原型对象
//类装饰器 function login(params:any){ return function(target:any){ } } //属性装饰器 function log(params:any){ return function(target:any,attr:any){ target[attr]=params } } @login("hello") class fun{ @log("word") api:string|undefined; constructor(){ this.api="我是fun中的api" } get(){ console.log(this.api) } } var a=new fun() a.get()