18装饰器
# 装饰器
装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。 装饰器使用
@expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。简单的说装饰器就是一种非侵入式修改。
- 在
TypeScript中装饰器还属于实验性语法,你必须在命令行或tsconfig.json里启用。
{ "experimentalDecorators": true}
1
# 1、类装饰器
function fn(target:Function){
target.prototype.name = "小明"
}
@fn
class Person {
public name!:string//这里的叹号指得是name的值非null、非为定义。
}
let p = new Person()
console.log(p.name)//小明
//传参数写法
function fn(name:string){
// return function(target:any){} //这是function写法
return (target:Function)=>{
target.prototype.name = name
}
}
@fn("小红")
class Person {
public name!:string
}
let p = new Person()
console.log(p.name)//小红;
//可用于重写构造函数
function fn(target:any){
return class extends target{
name = "小红"
}
}
@fn
class Person{
constructor(){
this.name= "小明"
}
name:string
}
let p = new Person()
console.log(p)//小红
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
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
# 2、属性装饰器
function fn(params:any){
return function(target:any,name:any){
// console.log(params) 参数
// console.log(target) 对象原型
// console.log(name) 属性名
target.name = params
}
}
class Person{
@fn("小明")
name:string | undefined
}
let p = new Person()
console.log(p.name)//小明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 3、方法装饰器
- 它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。
//方法装饰器一共有3个参数,第一个参数在不同的方法上是不一样的。
//对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
function fn(target:any,key:any,descriptor:any){
console.log(target)
}
class Person{
@fn//p.__proto__
sayHello(){//实例方法
}
@fn//p.constructor
static sayHi(){//静态方法
}
}
let p = new Person()
//第二个参数key是方法名字
function fn(target:any,key:any,descriptor:any){
console.log(key)
}
class Person{
@fn//sayHello
sayHello(){
}
@fn//sayHi
static sayHi(){
}
}
//第三个参数是属性修饰对象
function fn(target:any,key:any,descriptor:any){
console.log(descriptor)
}
class Person{
//writable是否可以重写,enumerable是否可以枚举,configurable是否可以配置
@fn//{"writable":true,"enumerable":true,"configurable":true}
sayHello(){
}
@fn//{"writable":true,"enumerable":true,"configurable":true}
static sayHi(){
}
}
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
48
49
50
51
52
53
54
55
56
57
58
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
48
49
50
51
52
53
54
55
56
57
58
# 案例
//改写方法
function fn(target: any, name: any, descriptor: any) {
descriptor.value = ()=>{
console.log("hehe")
}
}
class Person {
@fn
sayHello() {
console.log("hello")
}
}
let p = new Person()
p.sayHello()//hehe
//设置方法为不可修改
function fn(target: any, name: any, descriptor: any) {
descriptor.writable = false
}
class Person {
@fn
sayHello() {
console.log("hello")
}
}
let p = new Person()
p.sayHello = function(){//报错,不可以修改
console.log("hehe")
}
p.sayHello()
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
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
编辑 (opens new window)
上次更新: 2023/08/06, 00:38:41