如何在装饰器的箭头函数中传递类的字段?
在装饰器的箭头函数中访问类实例字段是否可行?
我希望在传递给装饰器的箭头函数中使用类的字段,示例代码如下:
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
相关产品推荐
相关产品推荐

