装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为。
通俗的讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。
常见的装饰器有:
- 类装饰器
- 属性装饰器
- 方法装饰器
- 参数装饰器
装饰器的写法:
- 普通装饰器(无法传参)
- 装饰器工厂(可传参)
装饰器是过去几年中js最大的成就之一,已是Es7的标准特性之一
类装饰器
普通装饰器(无法传参)
function logClass(params:any){ console.log(params); // params 就是当前类 params.prototype.apiUrl='动态扩展的属性'; params.prototype.run=function(){ console.log('我是一个run方法'); } } @logClass class HttpClient{ constructor(){ } getData(){ } } var http:any=new HttpClient(); console.log(http.apiUrl); //动态扩展的属性 http.run(); //我是一个run方法
装饰器工厂(可传参)
function logClass(params:string){ return function(target:any){ console.log(target); //当前类:HttpClient console.log(params); //http://www.itying.com/api target.prototype.apiUrl=params; } } @logClass('http://www.itying.com/api') class HttpClient{ constructor(){ } getData(){ } } var http:any=new HttpClient(); console.log(http.apiUrl);
属性装饰器
属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。 2、成员的名字。//类装饰器 function logClass(params:string){ return function(target:any){ // console.log(target); // console.log(params); } }//属性装饰器function logProperty(params: any) { return function (target: any, attr: any) { console.log(target); console.log(attr); target[attr] = params; }}@logClass('xxxx')class HttpClient { @logProperty('监视属性') public url: any | undefined; constructor() { } getData() { console.log(this.url); }}var http = new HttpClient();http.getData();
方法装饰器
它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。
方法装饰会在运行时传入下列3个参数:
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。 2、成员的名字。 3、成员的属性描述符。扩展方法
正常的扩展方法.
function get(params:any){ return function(target:any,methodName:any,desc:any){ console.log(`0.params${params}`); console.log(`1.target:`); console.log(target); console.log("2.methodName:"); console.log(methodName); console.log("3.desc:"); console.log(desc); target.Apiurl='xxxx'; target.run=function(){ console.log('5.run'); } }}class HttpClient{ public url:any |undefined; constructor(){ } @get('param参数在这里~~~') getData(){ console.log("6.this.url"); console.log(this.url); }}var http:any=new HttpClient();console.log("4.http.Apiurl");console.log(http.Apiurl);http.run();http.getData();
修改方法内容
function get(params:any){ return function(target:any,methodName:any,desc:any){ // console.log(`0.params${params}`); // console.log(`1.target:`); // console.log(target); // console.log("2.methodName:"); // console.log(methodName); // console.log("3.desc:"); // console.log(desc); //修改装饰器的方法 把装饰器方法里面传入的所有参数改为string类型 let oMethod = desc.value; desc.value = function name(...args:any[]) { args = args.map(value=>{ return String(value); }) oMethod.apply(this,args); console.log(args); } }}class HttpClient{ public url:any |undefined; constructor(){ } @get('param参数在这里~~~') getData(){ console.log("这里是getData方法内~"); }}var http:any=new HttpClient();http.getData(123,"aabb");