Js装饰器

更新日期: 2019-10-19阅读: 2.4k标签: 装饰器

装饰器

  • 装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为。
  • 通俗的讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。
  • 常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器
  • 装饰器的写法:普通装饰器(无法传参) 、 装饰器工厂(可传参)
  • 装饰器是过去几年中js最大的成就之一,已是Es7的标准特性之一


1.类修饰器

①类装饰器:普通装饰器(无法传参)

 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();


②类装饰器:装饰器工厂(可传参)

   function logClass(params:string){
       return function(target:any){
           console.log(target);
           console.log(params);
           target.prototype.apiUrl=params;
       }
   }

   @logClass('http://www.itying.com/api')
   class HttpClient{
       constructor(){
       }
       getData(){
       }
   }

   var http:any=new HttpClient();
   console.log(http.apiUrl);


③类装饰器 重构构造函数

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{
	public apiUrl:string | undefined;
	constructor(){
		this.apiUrl='我是构造函数里面的apiUrl';
	}
    getData(){
        console.log(this.apiUrl);
    }
}

var http=new HttpClient();
http.getData();



2.属性修饰符

属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:

1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。

2、成员的名字。

function logProperty(params:any){
        return function(target:any,attr:any){
            console.log("logProperty",target);
            console.log("logProperty",attr);
            target[attr]=params;
        }
    }
    
 class HttpClient{
     @logProperty('http://itying.com1')
     public url:any |undefined;
     constructor(){
     }
     getData(){
     	console.log(this.url);
     }
 }
 var http=new HttpClient();
 http.getData();



3.方法装饰器

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

    //修改装饰器的方法  把装饰器方法里面传入的所有参数改为string类型

    //1、保存当前的方法

    var oMethod=desc.value;
        desc.value=function(...args:any[]){                
            args=args.map((value)=>{
            	return String(value);
            })
            oMethod.apply(this,args);
            }
        }
    }
class HttpClient{  
    public url:any |undefined;
    constructor(){
    }
    @get('http://www.itying,com')
    getData(...args:any[]){
        console.log(args);
        console.log('我是getData里面的方法');
    }
}

var http=new HttpClient();
http.getData(123,'xxx');


4.参数装饰器

参数装饰器表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据 ,传入下列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 HttpClient{
public url:any |undefined; constructor(){ }
getData(@logParams('xxxxx') uuid:any){
console.log(uuid); } }
var http:any = new HttpClient(); http.getData(123456); console.log( http.apiUrl);


总结:

执行顺序: 属性》方法》方法参数》类;如果有多个同样的装饰器,它会先执行后面的


链接: https://fly63.com/article/detial/6479

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!