应用装饰器后类方法内部this变为undefined该如何解决?
问题根因
this丢失问题是两个错误用法共同导致的:
- 装饰器中重写
descriptor.value时使用了箭头函数:箭头函数的this在定义阶段就绑定了上层作用域的this,而装饰器工厂函数是在类定义阶段执行的,此时上层作用域的this在严格模式下为undefined,和类实例没有任何关系。 - 你给
UseAfter函数加的this类型注解没有实际作用:装饰器工厂执行时的this指向的是全局上下文,不会指向后续创建的类实例。
修复方案
将重写descriptor.value的箭头函数替换为普通函数,普通函数的this会在运行时动态绑定到调用该方法的类实例上:
// 修复后的装饰器 function UseAfter(fn: (...args: any) => any){ return (target: any, key: string, descriptor: PropertyDescriptor) => { const originalMethod = descriptor.value // 改用普通函数,运行时this会指向类实例 descriptor.value = function(...innerArgs:any) { const result = originalMethod.apply(this, innerArgs) return fn(result) } } } const middleware = (arg1: any) => { return { data: JSON.stringify(arg1) } } class Test { otherInstanceMethod() { console.log('accessing instance method') } @UseAfter(middleware) method1() { console.log(this) // 输出Test类实例 this.otherInstanceMethod() return 'ok' } } const test = new Test() test.method1() // 正常运行,返回 {data: "\"ok\""}
扩展说明
如果需要支持异步方法的返回值处理,可以增加Promise判断逻辑:
function UseAfter(fn: (...args: any) => any){ return (target: any, key: string, descriptor: PropertyDescriptor) => { const originalMethod = descriptor.value descriptor.value = function(...innerArgs:any) { const result = originalMethod.apply(this, innerArgs) // 兼容异步返回值 return result instanceof Promise ? result.then(fn) : fn(result) } } }
内容的提问来源于stack exchange,提问作者username_jj
相关产品推荐
相关产品推荐

