typescript装饰器含义,用法以及写法

装饰器

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

  2. 类装饰器:
    类装饰器在声明之前被声明(紧靠着类声明)。类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。传入一个参数

    //普通装饰器(无法传参)
    	//装饰器
    	function logClass(params:any){
    		//params就是当前类
    		console.log(params); //f HttpClient() {}
    		params.prototype.apiUrl = "xxxx"//相当于动态扩展的属性
    		params.prototype.run = function(){
    			console.log("run")
    		}
    	}
    	
    	@logClass
    	class HttpClient{
    		constructor(){}
    		getData(){}
    	}
    
    	var http:any = new HttpClient();
    	console.log(http.apiUrl);//xxxx
    	http.run();//run
    
    	//装饰器工厂(可传参)
    	//装饰器
    	function logClass(params:string){
    		return function(target:any){
    			console.log(target); //f HttpClient() {}
    			console.log(params); //http://www.abc.com
    			target.prototype.apiUrl = params;//相当于动态扩展的属性
    		}
    	}
    	
    	@logClass("http://www.abc.com")
    	class HttpClient{
    		constructor(){}
    		getData(){}
    	}
    
    	var http:any = new HttpClient();
    	console.log(http.apiUrl);//http://www.abc.com
    

    重载构造函数的例子:
    类装饰器表达式会在运行时当做函数被调用,类的构造函数作为其唯一的参数。
    如果类装饰器返回一个值,他会使用提供的构造函数来替换类的声明。

    	function logClass(target:any){
    		console.log(target);// f HttpClient(){this.apiUrl="构造函数里的apiUrl"}
    		return class extends target {
    			apiUrl:any = "修改的apiUrl";
    			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();//修改的apiUrl----
    
  3. 属性装饰器
    属性装饰器表达式会在运行时当做函数被调用,传入下2个各参数;

    • 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
    • 成员的名字。
    	//类装饰器
    	function logClass(params:string){
    		return function(target:any){
    			console.log(target); //f HttpClient() {}
    			console.log(params); //http://www.abc.com
    			target.prototype.apiUrl = params;//相当于动态扩展的属性
    		}
    	}
    	//属性装饰器
    	function logProperty(params:any){
    		return function(target:any,attr:any){
    			console.log(targrt);//{getData:f,constructor:f}
    			console.log(attr);//url
    			target[attr] = params;
    		}
    	}
    	
    	@logClass("xxxx")
    	class HttpClient{
    		@logProperty("http://www.abc.com") //属性装饰器后面不能加分号
    		public url:any|undefined;
    		constructor(){}
    		getData(){
    			console.log(this.url)
    		}
    	}
    
    	var http:any = new HttpClient();
    	http.getData();//http://www.abc.com
    
  4. 方法装饰器
    它会被用应到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。
    方法装饰会在运行时传入下列3个参数:

    1. 于静态成员来说是类的构造函数,对于实例成员是类的原型对象
    2. 成员的名字
    3. 成员的属性描述符
    	//方法装饰器一
    	function get(params:any){
    		return function(target:any,methodName:any,desc:any){
    			console.log(target)//{getData:f,constructor}原型对象
    			console.log(methodName)//getData当前方法的名称
    			console.log(desc)//{value:f,writable:true,enumerable:true,configurable:true}描述当前的方法,value就是当前的方法
    			target.apiUrl="xxxx";
    			target.run = function(){
    				console.log("run")
    			}
    		}
    	}
    	class HttpClient{
    		public url:any|undefined;
    		constructor(){}
    		@get("http://www.abc.com")
    		getData(){
    			console.log(this.url)
    		}
    	}
    	var http = new HttpClient();
    	console.log(http.apiUrl)//xxxx
    	http.run()//run
    
    	//方法装饰器二	
    	function get(params:any){
    		return function(target:any,methodName:any,desc:any){
    			console.log(target)//{getData:f,constructor}原型对象
    			console.log(methodName)//getData当前方法的名称
    			console.log(desc)//{value:f,writable:true,enumerable:true,configurable:true}描述当前的方法,value就是当前的方法
    			//修改装饰器的方法 把装饰器方法里面传入的所有参数改为string类型
    			//1、保存当前的方法
    			var oMethod = desc.value;
    			desc.value = function(...args:any[]){
    				args=args.map((val)=>{
    					return String(val)
    				})
    				console.log(args);//["aaa","xxx"]
    				oMethod.apply(this.args);
    			}
    		}
    	}
    	class HttpClient{
    		public url:any|undefined;
    		constructor(){}
    		@get("http://www.abc.com")
    		getData(...args:any){
    			console.log(args);//["aaa","xxx"]
    			console.log("getData里的方法")//getData里的方法
    		}
    	}
    	var http = new HttpClient();
    	http .getData(aaa,"xxx")
    
  5. 方法参数装饰器
    参数装饰器表达式会在运行时当做函数被调用,可以使用参数装饰器为类的原型增加一些元素数据,传入下列3个参数:

    1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
    2. 参数的名字
    3. 参数在函数参数列表中的索引
    	function logParams(params:any){
    		return function(target:any,paramsName:any,paramsIndex:any){
    			console.log(params);//xxxx
    			console.log(targrt);//{getData:f,constructor:f}
    			console.log(paramsName);//getData
    			console.log(paramsIndex);//0
    			
    			target.apiUrl=params;
    		}
    	}
    	
    	class HttpClient{
    		public url:any|undefined;
    		constructor(){}
    		getData(@logParams("xxxx") uuid:any){
    			console.log(uuid)//123123
    		}
    	}
    	var http:any = new HttpClient();
    	http .getData(123123);
    	console.log(http.apiUrl);//xxxx
    	
    
  6. 装饰器执行顺序:
    属性>方法>方法参数>类
    如果有多个同样的装饰器,先执行后面的

    	function logClass1(params:any){
    		return function(target:any){
    			console.log("装饰器1");
    		}
    	}
    	function logClass2(params:any){
    		return function(target:any){
    			console.log("装饰器2");
    		}
    	}
    	function logAttribute(params?:string){
    		return function(target:any,attrName:any){
    			console.log("属性装饰器");
    		}
    	}
    	function logMethod(params?:string){
    		return function(target:any,attrName:any,desc:any){
    			console.log("方法装饰器");
    		}
    	}
    	function logParams1(params?:string){
    		return function(target:any,attrName:any,desc:any){
    			console.log("方法参数装饰器1");
    		}
    	}
    	function logParams2(params?:string){
    		return function(target:any,attrName:any,desc:any){
    			console.log("方法参数装饰器1=2");
    		}
    	}
    	@logClass2("aaa")
    	@logClass2("xxx")
    	class HttpClient{
    		@logAttribute()
    		public apiUrl:any|undefined;
    		constructor(){}
    		@logMethod()
    		getData(){
    			return true;
    		}
    		setData(@logParams1() attr1:any,@logParams2 attr2:any){
    			
    		}
    	}
    	var http:any = new HttpClient();
    	//属性装饰器
    	//方法装饰器
    	//方法参数装饰器2
    	//方法参数装饰器1
    	//类装饰器2
    	//类装饰器1
    
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苟圣啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值