0%

装饰器

装饰器

_装饰器_是一种特殊类型的声明,它能够被附加到类声明方法访问符属性参数上。 装饰器使用@expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。

装饰器工厂

定制一个修饰器如何应用到一个声明上,得写一个装饰器工厂函数,装饰器工厂就是一个简单的函数,它返回一个表达式,以供装饰器在运行时调用

1
2
3
4
5
function color(value: string) { // 这是一个装饰器工厂
return function (target) { // 这是装饰器
// do something with "target" and "value"...
}
}

类装饰器

应用于类构造函数,可以用来监视,修改或替换类定义。类装饰器不能用在声明文件中(.d.ts),也不能用在人格化外部上下文中

类装饰器表达式会在运行是被当做函数被调用,类的构造函数作为其唯一的参数。

如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function logClass(params:string){
return function(target:any){
console.log(target);//类
console.log(params);//传入的参数
target.prototype.apiurl=params;
}
}
@logClass("http://123.com")*
class HttpClient {
constructor(){

}
gatData(){

}

}
var http:any=new HttpClient();

重载构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function logClass<T extends {new(...args:any[]):{}}>(constructor:T){
console.log(constructor);
return class extends constructor {
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);
}
}
let http:any=new HttpClient();
http.getData();

方法装饰器

声明在一个方法的声明之前(紧靠着方法声明),他会被应用到方法的属性描述符上,可以用来监视,修改或者替换方法定义。方法装饰器不能用在声明文件(.d.ts),重载或者任何外部上下文中

方法装饰器表达式会在运行时当做函数被调用,传入下列3个参数:

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

2 方法的名字

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
28
29
30
31
32
33
34
35
36
37
38
39
function get(params:any){
return function(target:any,methodName:any,desc:any){
console.log(target);//类的原型对象
console.log(methodName)//getData
console.log(desc.value)
//ƒ getData(...args) {
// console.log(args);
//console.log.toString("我是getData里面的方法");
//}
//修改方法装饰器,改为可以传入参数
//保存当前方法
let oMethod=desc.value;
desc.value=function(...args:any[]){
args.map((val)=>{
return String(val);
})
console.log(this);//类
oMethod.apply(this,args);
}



}

}
class HttpClient {
url: any | undefined;
constructor(){

}
@get('123')
getData(...args:any[]){
console.log(args);
console.log.toString("我是getData里面的方法")
}

}
let http=new HttpClient();
http.getData('123',456);

属性装饰器

声明在一个属性声明之前,属性装饰器不能用纸声明文件中(.d.ts),或者任何外部上下文(比如declare的类)里

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

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

2 属性的名字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function logProperty(params:any){
return function (target:any,attr:any){
console.log(target);//类的原型对象
console.log(attr);//url
target[attr]=params;
}
}
class HttpClient {
@logProperty('http://123.com')
url:any | undefined;
constructor(){
}
getData(){
console.log(this.url);
}
}
var http=new HttpClient();
http.getData();

参数装饰器

参数装饰器_声明在一个参数声明之前(紧靠着参数声明)。 参数装饰器应用于类构造函数或方法声明。 参数装饰器不能用在声明文件(.d.ts),重载或其它外部上下文(比如declare的类)里。

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

  1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
  2. 成员的名字。
  3. 参数在函数参数列表中的索引

装饰器作用:扩展类的方法和属性

装饰器执行顺序:

属性>方法>方法参数>类

多个同样的装饰器,执行顺序由后往前