此装饰器和我理解的java中的「注解」还不是一个意思,java中的注解回顾
这里有完整的装饰器解释
装饰器 不过是在设计时(design time)帮助内省代码,注解**及修改类和属性的函数
装饰器和注解
- 装饰器(Decorator) 仅提供定义劫持,能够对类及其方法、方法入参、属性的定义并没有提供任何附加元数据的功能。
- 注解(Annotation) 仅提供附加元数据支持,并不能实现任何操作。需要另外的 Scanner 根据元数据执行相应操作。
注意到装饰器是对类及其方法、入参、属性行为的修改,而注解只是添加元数据,不能修改行为。
@modifyClass
class A {
}
function modifyClass(target: any) {
target.prototype.extraProp = 'decorator'
}
在装饰器的方法中,入参是target,作用于class A上就是 A ,我们知道,在ES中一切都是对象,class 是ES6以后的一个面向对象的语法糖,在这里的A本质也就是一个function,在新建实例的时候作为构造函数调用。这里通过target.prototype我们也能获得这个类的原型。这样我们就可以对这个类进行修改了。
装饰器是在编译期间发生的,这个时候类的实例还没有生成,因此装饰器无法直接对类的实例进行修改。但是可以间接的通过修改类的原型影响实例
这样的修饰器意义不大,我们要应对更多的情况,因此可以给修饰器加上参数,或者叫做「注解」
@modifyClass('param')
class A {
}
function modifyClass(param) {
return target => {
target.prototype.extraProp = param
}
}
之所以要给注解添加引号,是因为注解的概念是要进行元数据的修改,而这里仅仅是动态改变原型上的属性。要进行元数据的修改,我们需要利用反射Reflect。 ES6提供的Refelct并不满足修改元数据,我们要额外引入一个库reflect-metadata
import 'reflect-metadata'
@modifyClass('param')
class A {
}
function modifyClass(param) {
return target => {
Reflect.defineMetadata(Symbol.for('META_PARAM'), param, target.prototype)
}
}
反射给了我们在类及其属性、方法、入参上存储读取数据的能力