You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在装饰器的箭头函数中传递类的字段?

在装饰器的箭头函数中访问类实例字段是否可行?

我希望在传递给装饰器的箭头函数中使用类的字段,示例代码如下:

export function decorator(nameOrNameFn: string | ((...args: any[]) => string)) {
    return function (value: Function, context: ClassMethodDecoratorContext) {
        return function (this: any, ...args: any[]) {
            const name = typeof nameOrNameFn === 'function' ? nameOrNameFn.apply(this, args) : nameOrNameFn;
            console.log(name);
            value.apply(this, args);
        };
    };
}

class Example {
    readonly field: string;

    constructor(field: string) {
        this.field = field;
    }

    @decorator(param => `Logging inside decorator: ${param} + ${this.field}`)
    method(param: string) {
        console.log('Logging inside method: ' + param)
    }
}

new Example('fieldValue').method('paramValue');

我知道可以通过传递普通函数实现该需求:

@decorator(function (t) {
    return `User "${this.email}" receives "${t.mailSubject}" email`;
})

但我更倾向于使用箭头函数或类似方式实现,是否可行?


不行,箭头函数无法实现这个需求,核心原因是箭头函数的this是词法绑定的:

  • 装饰器在类定义阶段就会执行,此时箭头函数的this会绑定到它定义时的上下文(比如浏览器环境的window、Node.js环境的globalThis,严格模式下则是undefined),而非类的实例对象。
  • 当你在箭头函数里访问this.field时,这个this根本指向不到类的实例,运行时会抛出类似Cannot read properties of undefined (reading 'field')的错误。

而普通函数能生效的原因是:普通函数的this是动态绑定的,你的装饰器实现中通过nameOrNameFn.apply(this, args),把类实例的this绑定给了普通函数,所以它能正常访问实例字段。

如果想尽量贴近箭头函数的简洁写法,可以调整装饰器设计,让传入的函数接收实例作为第一个参数:

export function decorator(nameFn: (instance: any, ...args: any[]) => string) {
    return function (value: Function, context: ClassMethodDecoratorContext) {
        return function (this: any, ...args: any[]) {
            const name = nameFn(this, ...args);
            console.log(name);
            value.apply(this, args);
        };
    };
}

// 使用示例
class Example {
    readonly field: string;

    constructor(field: string) {
        this.field = field;
    }

    @decorator((instance, param) => `Logging inside decorator: ${param} + ${instance.field}`)
    method(param: string) {
        console.log('Logging inside method: ' + param)
    }
}

这种方式既保留了箭头函数的写法,又能通过参数获取类实例,从而访问实例字段。

内容的提问来源于stack exchange,提问作者kosteklvp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:18:25