类装饰器
//类装饰器
namespace a {
function addNameEat(constructor: Function) {
constructor.prototype.name = 'zhufeng';
constructor.prototype.eat = function () { }
}
@addNameEat
class Person {
name: string;
eat: Function;
constructor() { }
}
let p: Person = new Person();
console.log(p.name);
p.eat();
}
//类装饰器工厂
namespace b {
function addNameEatFactory(name: string) {
return function addNameEat(x: Function) {
x.prototype.name = name;
x.prototype.eat = function () { }
}
}
@addNameEatFactory('jiagou')
class Person {
name: string;
eat: Function;
constructor() { }
}
let p: Person = new Person();
console.log(p.name);
p.eat();
}
// 类型安全
namespace c {
function replaceClass(constructor: Function) {
return class {
name: string;
eat: Function;
age: number; // 属性可以多,但不能少
constructor() { }
}
}
@replaceClass
class Person {
name: string;
eat: Function;
constructor() { }
}
let p: Person = new Person();
console.log(p.name);
p.eat();
}
属性装饰器
// 属性装饰器:装饰属性、装饰方法
namespace d {
// 如果装饰的是实例属性的话,target 是构造函数的原型
function upperCase(target: any, propertyKey: string) {
let value = target[propertyKey];
if (delete target[propertyKey]) {
Object.defineProperty(target, propertyKey, {
get: () => value,
set: (newVal: string) => { value = newVal.toUpperCase() },
enumerable: true,
configurable: true
});
}
}
// 如果装饰的是静态属性的话,target 是构造函数本身
function staticPropertyDecorator(target: any, propertyKey: string) {
console.log(target, propertyKey);
}
function noEnumerable(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log(target);
console.log(propertyKey);
descriptor.enumerable = false;
}
function toNumber(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
let oldMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
args = args.map(item => parseFloat(item));
return oldMethod.apply(this, args);
}
}
class Person {
@upperCase
name: string = 'zhangsan'; //实例属性
@staticPropertyDecorator
static age: number = 10; //静态属性
@noEnumerable
getName() { console.log(this.name); }//实例方法
@toNumber
sum(...args: any[]) {//实例方法
return args.reduce((accu: number, item: number) => accu + item, 0);
}
}
let p = new Person();
console.log(p.name);
console.log(p.sum('1', '2', '3'));
}
参数装饰器
namespace e {
// 在 IOC 容器里大放异彩 Nest.js 大量的用到了参数装饰器
// 参数列表:静态成员就是构造函数,非静态成员就是构造函数原型、方法的名称、参数的索引
function addAge(target: any, methodName, paramIndex: number) {
console.log(target, methodName, paramIndex);
target.age = 10;
}
class Person {
age: number;
login(username: string, @addAge password: string) {
console.log(this.age, username, password);
}
}
let p = new Person();
p.login('1', '2');
}
装饰器的执行顺序
/**
* 装饰器执行顺序的规律(一般从内往外执行 先内后外)
* 1.类装饰器是最后执行的,后写的类装饰器先执行
* 2.方法和方法参数中的装饰器先执行参数
* 3.方法和属性装饰器,谁在前面先执行谁
*/
namespace f {
function ClassDecorator1() {
return function (target) {
console.log('ClassDecorator1');
}
}
function ClassDecorator2() {
return function (target) {
console.log('ClassDecorator2');
}
}
function PropertyDecorator(name: string) {
return function (target, propertyName) {
console.log('PropertyDecorator', propertyName, name);
}
}
function MethodDecorator() {
return function (target, propertyName) {
console.log('MethodDecorator', propertyName);
}
}
function ParameterDecorator() {
return function (target, methodName, index) {
console.log('ParameterDecorator', methodName, index);
}
}
@ClassDecorator1()
@ClassDecorator2()
class Person {
@PropertyDecorator('name')
name: string = '';
@PropertyDecorator('age')
age: number = 10;
@MethodDecorator()
hello(@ParameterDecorator() p1: string, @ParameterDecorator() p2: string) { }
}
}
打赏作者
您的打赏是我前进的动力
微信
支付宝
类
上一篇
评论