初识
什么是装饰器?
在一些场景下我们需要额外的特性来支持标注或修改类及其成员。我们使用装饰器来实现。
装饰器是一种设计模式,可以动态的实现对类属性的修改,而不需要重载,实现了最大的灵活性。
ts中装饰器怎样实现?
首先运行时开启:
tsc yourDecorator.ts --target ES5 --experimentalDecorators
或者使用配置方式:
tsconfig.json
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
ts中装饰器使用 @expression
这种形式,expression
求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。
一个简单的示例(装饰器只在解释执行时应用一次。即使没有使用C类,也会打印"hello world"):
// example1
function helloWorld(target: any) {
console.log("hello world");
}
@helloWorld
class C {
constructor() {
console.log("this is constructor");
}
}
// 结果
// hello world
// example2
function hello(name: string): any {
return function () {
console.log("hello,", name);
};
}
@hello("Pig")
class Pig {
constructor() {
console.log("this is the Pig constructor");
}
}
// 结果
// hello pig
五种装饰器
- 类装饰器
- 属性装饰器
- 方法装饰器
- 访问器装饰器
- 参数装饰器
// 类装饰器
@classDecorator
class Bird {
// 属性装饰器
@propertyDecorator
name: string;
// 方法装饰器
@methodDecorator
fly(
// 参数装饰器
@parameterDecorator
meters: number
) {}
// 访问器装饰器
@accessorDecorator
get egg() {}
}
执行顺序
1. 实例成员
1.1实例成员参数装饰器
1.2实例成员方法、访问器、属性装饰器
2. 静态成员
1.1静态成员参数装饰器
1.2静态成员方法、访问器、属性装饰器
3. 构造器参数装饰器
4. 类装饰器
function f(key: string): any {
console.log("evaluate: ", key);
return function () {
console.log("call: ", key);
};
}
@f("Class Decorator")
class C {
@f("Instance Property")
prop?: number;
@f("Static Property")
static prop?: number;
@f("Static Method")
static method(@f("Static Method Parameter") foo) {}
constructor(@f("Constructor Parameter") foo) {}
@f("Instance Method")
method(@f("Instance Method Parameter") foo) {}
}
结果如下:
evaluate: Instance Property
call: Instance Property
evaluate: Instance Method
evaluate: Instance Method Parameter
call: Instance Method Parameter
call: Instance Method
evaluate: Static Property
call: Static Property
evaluate: Static Method
evaluate: Static Method Parameter
call: Static Method Parameter
call: Static Method
evaluate: Class Decorator
evaluate: Constructor Parameter
call: Constructor Parameter
call: Class Decorator
注意点:
1. 装饰器执行顺序是后进先出
1.1 多参数情况,最后一个参数的装饰器会最先被执行
1.2 装饰器工厂:它返回一个表达式,以供装饰器在运行时调用,多个装饰器工厂,最后一个装饰器返回表达式最先执行。
1.3 装饰器工厂外部的代码是按照顺序执行,并不是后进先出。
function f(key: string) {
console.log("evaluate: ", key);
return function () {
console.log("call: ", key);
};
}
class C {
@f("Outer Method")
@f("Inner Method")
method() {}
}
输出:
evaluate: Outer Method
evaluate: Inner Method
call: Inner Method
call: Outer Method
2. 因为ts的类设计原则中,构造器相当于这个类,所以构造器没有所谓的方法装饰器,构造器的 "方法装饰器" 其实就是类装饰器。
五种装饰器具体实现
看下面的博文~~👇🏻
推荐博文
装饰器 · TypeScript中文网 · TypeScript——JavaScript的超集
TypeScript装饰器,一篇就够了_SuperBin的博客-CSDN博客_typescript 装饰器