type ClassMethodDecorator = (
value: Function,
context: {
kind: 'method';
name: string | symbol;
static: boolean;
private: boolean;
access: { get: () => unknown };
addInitializer(initializer: () => void): void;
}
) => Function | void;
1、如果装饰器返回一个函数就会替代装饰的函数
function replaceMethod(
originMethod: Function,
content: ClassMethodDecoratorContext
) {
return function (...args) {
console.log(args);
originMethod.call(this, args);
};
}
2、装饰器可以传参数
@replaceMethod('7777')
myMethod
function replaceMethod(...args) {
return function (
originMethod: Function,
content: ClassMethodDecoratorContext
) {
return function (...hello) {
originMethod.call(this,hello);
};
};
}
装饰器接参数重新类中的方法 停留时间执行
function Greeter(value: any, context: any) {}
function replaceMethod(num: number) {
return function (
originMethod: Function,
content: ClassMethodDecoratorContext
) {
return function (...hello) {
setTimeout(() => {
originMethod.call(this, hello);
}, num);
};
};
}
@Greeter
class User {
[propertyName: string]: any;
name: string;
constructor(name: string) {
this.name = name;
}
@replaceMethod(1000)
hello(u) {
console.log("元旦快乐" + " " + this.name + u);
}
}
let u = new User("zhansan");
u.hello("0999");
3、方法装饰器的 { addInitializer } 相当于constructor 初始化对象?参数是一个函数,可以访问当前this
function initialInstance(
originMethod: Function,
content: ClassMethodDecoratorContext
) {
content.addInitializer(function () {
this[content.name] = this[content.name].bind(this);
});
}
class Person {
name: string;
constructor(name: string) {
this.name = name;
// greet() 绑定 this
// this.greet = this.greet.bind(this);
}
@initialInstance
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
}
4、一个方法可以有多个装饰器
/**
*
* @param originMethod @type {Function}
* @param content @type {ClassMethodDecoratorContext}
*/
function collectMethods(
originMethod: Function,
{ addInitializer, name }: ClassMethodDecoratorContext
) {
addInitializer(function () {
let _this = this as Person;
if (!_this.collectMethodSet) {
_this.collectMethodSet = new Set();
}
_this.collectMethodSet.add(name);
});
}
function initialInstance(
originMethod: Function,
content: ClassMethodDecoratorContext
) {
content.addInitializer(function () {
this[content.name] = this[content.name].bind(this);
});
}
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
[p: string]: any;
@initialInstance
@collectMethods
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
@collectMethods
handle() {}
}
const g = new Person("张三");
g.greet() //Hello, my name is 张三
console.log(g.collectMethodSet); //Set(2) { 'greet', 'handle' }