看啥推荐读物
专栏名称: 2o壹9
目录
相关文章推荐
今天看啥  ›  专栏  ›  2o壹9

TypeScript——装饰器(二)

2o壹9  · 简书  ·  · 2019-12-22 18:02

装饰器求值

类中不同声明上的装饰器将按以下规定的顺序应用:

参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个实例成员。

参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个静态成员。

参数装饰器应用到构造函数。

类装饰器应用到类。

类装饰器

类装饰器在类声明之前被声明(紧靠着类声明)。 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。 类装饰器不能用在声明文件中( .d.ts),也不能用在任何外部上下文中(比如declare的类)。

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

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

注意  如果你要返回一个新的构造函数,你必须注意处理好原来的原型链。 在运行时的装饰器调用逻辑中 不会为你做这些。

下面是使用类装饰器(@sealed)的例子,应用在Greeter类:

@sealed

class Greeter {

greeting: string;

constructor(message: string) {

this.greeting = message;

}

greet() {

return "Hello, " + this.greeting;

}

}

我们可以这样定义@sealed装饰器:

function sealed(constructor: Function) {

Object.seal(constructor);

Object.seal(constructor.prototype);

}

当@sealed被执行的时候,它将密封此类的构造函数和原型。(注:参见Object.seal)

下面是一个重载构造函数的例子。

function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {

return class extends constructor {

newProperty = "new property";

hello = "override";

}

}

@classDecorator

class Greeter {

property = "property";

hello: string;

constructor(m: string) {

this.hello = m;

}

}

console.log(new Greeter("world"));

方法装饰器

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

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

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

成员的名字。

成员的属性描述符。

注意  如果代码输出目标版本小于ES5,属性描述符将会是undefined。

如果方法装饰器返回一个值,它会被用作方法的属性描述符。

注意  如果代码输出目标版本小于ES5返回值会被忽略。

下面是一个方法装饰器(@enumerable)的例子,应用于Greeter类的方法上:

class Greeter {

greeting: string;

constructor(message: string) {

this.greeting = message;

}

@enumerable(false)

greet() {

return "Hello, " + this.greeting;

}

}

我们可以用下面的函数声明来定义@enumerable装饰器:

function enumerable(value: boolean) {

return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {

descriptor.enumerable = value;

};

}

这里的@enumerable(false)是一个装饰器工厂。 当装饰器 @enumerable(false)被调用时,它会修改属性描述符的enumerable属性。




原文地址:访问原文地址
快照地址: 访问文章快照