装饰器

Posted on Aug 2, 2022

原代码

class Spread {
    suspendPaint = () => { }
    resumePaint = () => { }
}
function spreadPerformance() {
    return function (target: A, propertyName: string, propertyDescriptor: PropertyDescriptor) {
        const method = propertyDescriptor.value;
        console.log('target', target)
        console.log('propertyName', propertyName)
        console.log('propertyDescriptor', propertyDescriptor)
        propertyDescriptor.value = function (...args: any[]) {
            console.log(1, this.name)
            method.call(this, ...args)
            console.log(2, this.name)
        };
        return propertyDescriptor;
    };
}
class A {
    constructor(public name: string) {
        A.age = 22
    }
    public static age = 18
    @spreadPerformance()
    fillDataToSpanCell(spread: Spread) {
        console.log(`run ${this.name}`, spread)
    }
}
const a = new A("hello")
a.fillDataToSpanCell(new Spread())

编译后

__decorate([
    spreadPerformance(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Spread]),
    __metadata("design:returntype", void 0)
], A.prototype, "fillDataToSpanCell", null);
  1. 装饰器只能作用与class,不能适用于纯函数。
  2. 各个参数是什么,target 是 A.prototype 原型,propertyName 是方法或属性名,propertyDescriptor.value 是方法本体
  3. 需要call或apply绑定 this 不然方法内有问题
  4. 装饰器函数内可以通过 this 拿到 A 类的实例