/**来源:https://www.tslang.cn/docs/handbook/decorators.html
* 1,装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。
* 2,在TypeScript里,当多个装饰器应用在一个声明上时会进行如下步骤的操作:
* 由上至下依次对装饰器表达式求值。
* 求值的结果会被当作函数,由下至上依次调用。
* 3,类中不同声明上的装饰器将按以下规定的顺序应用:
* 参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个实例成员。
* 参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个静态成员。
* 参数装饰器应用到构造函数。
* 类装饰器应用到类。
* 4,类装饰器:应用于类构造函数,可以用来监视,修改或替换类定义。
* 类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数
* 5,方法装饰器:会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。
* 方法装饰器表达式会在运行时当作函数被调用,传入下列3个参数:
* 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
* 成员的名字。
* 成员的属性描述符。
* 6,访问装饰器:一个成员的所有装饰的必须应用在文档顺序的第一个访问器上。
* 这是因为,在装饰器应用于一个属性描述符时,它联合了get和set访问器,而不是分开声明的。
* 访问器装饰器表达式会在运行时当作函数被调用,传入下列3个参数:
* 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
* 成员的名字。
* 成员的属性描述符。*/
//1,装饰器工厂
function color(value: string) {
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log(value);//5
}
}
//2,装饰器组合
function f(somObj: Object) {
console.log(somObj);//1
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log(descriptor.value.toString());//4,能输出函数的内容
}
}
function g() {
console.log("g(): evaluated");//2
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log(target.method.toString());//3,能输出函数的内容
}
}
class C {
@color("yellow")
@f({name: "hello function decorators"})
@g()
method() {
console.log(Object.keys(this))
}
}
//3,类装饰器
//{new(...args: any[]): Object} 这个应该是constructor的类型定义
function classDecoratorWithParams(params: Object) {
return function classDecorator<T extends {new(...args: any[]): Object}>(constructor: T) {
return class someNewClass extends constructor {//这个写法相当于继承了原始类,但只增加了构造方法
newProperty = params;
hello = "override";
}
}
}
function enumerable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.enumerable = value;
}
}
//Configurable:表示能否通过delete删除属性从而重新定义属性;
//只要一旦将configurable设置为false,将不能再调用Object.defineProperty()对属性的行为进行修改
function configurable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.configurable = false;
};
}
@classDecoratorWithParams({name: "some name"})
class Greeter {
property = "property";
hello: string;
constructor(m: string) {
this.hello = m;
}
@enumerable(false)
funForTestMethodDecorators() {
console.log(this.hello)
}
@configurable(false)
get propertyVisitorDecorator() {
return this.property;
}
set propertyVisitorDecorator(value: string) {
this.property = value;
}
}
let G20 = new Greeter("world");
/*someNewClass {//改了类名字了,不是Greeter,是someNewClass
property: 'property',
hello: 'override',
newProperty: { name: 'some name' } }*/
delete G20.propertyVisitorDecorator;//加不加configurable装饰器都删不了,不清楚原因啊~
for (let o in G20) {//没有funForTestMethodDecorators方法,删除装饰器就有了.
console.log(o)
}
//4,方法装饰器,enumerable
//5,访问器装饰器,configurable
//6,属性装饰器和参数装饰器都有些复杂,用的也不多,等用到再说吧。~
[TypeScript语法7]decorators
最新推荐文章于 2022-10-23 12:23:51 发布