类的装饰器
- 类的装饰器在不影响类的前提下对类进行扩展
由于装饰器目前是试验阶段,在ts中使用装饰器之前需要对tsconfig.json进行配置
"experimentalDecorators": true
装饰器
function testDecoration(constructor: any) {
console.log('123');
}
@testDecoration
class Test {
constructor() {}
}
装饰器本质上是一个函数,当类构造完成后,会执行类上的装饰器函数;
多个装饰器执行顺序
当有多个装饰器时,执行顺序从右到左,从下到上
(书写顺序)
function testDecoration(constructor: any) {
console.log('111');
}
function testDecoration1(constructor: any) {
console.log('222');
}
@testDecoration
@testDecoration1
class Test {
constructor() {}
}
如上先执行testDecoration1, 后执行testDecoration
装饰器覆盖类
装饰器属性以及方法会覆盖类中的属性及方法
function testDecoration(constructor: any) {
constructor.prototype.getName = () => {
console.log('decoration');
};
}
@testDecoration
class Test {
constructor() {}
getName() {
console.log('test');
}
}
const test = new Test();
test.getName();
类的工厂模式
装饰器可以根据不同的类返回不同的函数
function testDecoration(flag: boolean) {
if (flag) {
return function (constructor: any) {
constructor.prototype.getName = () => {
console.log('decoration');
};
};
} else {
return function (constructor: any) {};
}
}
@testDecoration(true)
class Test {
constructor() {}
}
const test = new Test();
(test as any).getName();
使用泛型继承的方式
function testDecoration<T extends new (...args: any[]) => any>(constructor: T) {
return class extends constructor {
name = 'tz';
getName() {
return this.name;
}
};
}
@testDecoration
class Test {
constructor(public name: string) {}
}
const test = new Test('hello');
(test as any).getName();
console.log(test, 'test'); // 'name: tz'
解决装饰器的方法用实例调用报错的问题
function testDecorationFactory() {
return function testDecoration<T extends new (...args: any[]) => any>(constructor: T) {
return class extends constructor {
name = 'tz';
getName() {
return this.name;
}
};
}
}
const Test = testDecorationFactory()(class {
constructor(public name: string) {}
})
const test = new Test('hello');
test.getName(); // 解决test报错的问题