装饰器
是一种特殊的类型声明,它能够被附加到类声明、方法、属性和参数上,可以修改类的行为。通俗来说就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。
常见装饰器方法:类装饰器、属性装饰器、方法装饰器、参数装饰器
写法:普通装饰器(无法传参) 装饰器工厂(可传参)
装饰器是过去几年中JS最大的成京之一,已是ES7的标准特性之一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
function logClass(params:any){ console.log(params); params.prototype.apiUrl='http://'; params.prototype.run=function(){ console.log('我是一个run方法'); }; } @logClass class HttpClient(){ constructor(){ } getData(){ } }
var http:any = new HttpClient(); http.apiUrl; http.run();
function logClass(params:string){ return function(target:any){ console.log(target); console.log(params); target.prototype.text=params; } }
@logClass('hello') class HttpClient(){ constructor(){ } getData(){ } }
var http:any = new HttpClient(); http.text;
|
1、类装饰器:重截构造函数的例子
如果类装饰器返回一个值,它会使用提供的构造函数替换类的声明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function logClass(target:any){ console.log(target); return class extends target{ apiUrl:any="我是修改后的数据"; getData(){ this.apiUrl = this.apiUrl + '====='; console.log(this.apiUrl); } } }
@logClass class HttpClient(){ apiUrl : string | undefined; constructor(){ this.apiUrl = '我是构造函数里面的apiUrl'; } getData(){ console.log(this.apiUrl); } } var http:any = new HttpClient(); http.getData();
|
2、属性装饰器
对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
成员名字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| function logClass(params:any){ return function(target:any){ } }
function logProerty(params:any){ return function(target:any,attr:any){ console.log(target); console.log(attr); target[attr] = params; } }
@logClass('xxx') class HttpClient(){ @logProerty('http://') public url:any|undefined; constructor(){ } getData(){ console.log(this.url); } }
var http:any = new HttpClient(); http.url;
|
3、方法装饰器
修改当前实例的属性和方法
修改当前里的参数修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| function get(params:any){ return function(target:any,methodName:any,desc:any){ console.log(target); console.log(methodName); console.log(desc.value); target.url = 'xxx'; var oMethod = desc.value; desc.value = function(...args:any[]){ args = args.map((value)=>{ return String(value); }) oMethod.apply(this,args); } } } class HttpClient(){ public url:string | undefined; constructor(){ } @get('http://www.baidu.com') // !!重点 getData(...args:any[]){ console.log('我是getdata里的方法'); } } var n = new HttpClient(); http.getData(123,'123123');
|
4、方法参数装饰器
参数装饰器表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据,传入以下三个参数
1、对表态成员来说是类的构造函数,对实例成员是类的原型对象
2、方法的名字
3、参数在函数参数列表中的索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function logParams(params:any){ return function(target:any,methodName:any,paramsIndex:any){ console.log(params); console.log(target); console.log(methodName); console.log(paramsIndex); } } class HttpClient(){ public url:string | undefined; constructor(){ } getData(@logParams('uuid') uuid:any){ console.log(uuid); } } var http = new HttpClient(); http.getData(123);
|
执行顺序
属性 》 方法 》 方法参数 》 类
如果有多个同样的装饰器,它会先执行后面的!!!