TypeScript方法装饰器为何无法正确输出类的this.users值?
问题根源
你在装饰器里用apply传的target是类的原型对象,不是new UserService()创建的实例。你的users是实例属性(挂载在实例上),原型上根本没有这个属性,所以this.users自然是undefined。
正确写法
方法装饰器的第三个参数descriptor里的value才是原方法,调用它的时候要把**当前执行上下文(也就是实例)**传进去,而不是装饰器第一个参数的target。
修正后的装饰器代码:
function methodDecorator() { return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log('I am decorator!'); // 这里的this就是调用方法的实例 const result = original.apply(this, args); console.log(this.users); // 现在能拿到100了 return result; }; return descriptor; }; }
完整示例
interface IUserService { get(): number; } function methodDecorator() { return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log('I am decorator!'); const result = original.apply(this, args); console.log(this.users); return result; }; return descriptor; }; } class UserService implements IUserService { users = 100; @methodDecorator() get(): number { console.log(1); return 1; } } new UserService().get(); // 输出顺序: // I am decorator! // 1 // 100
关键解释
- 方法装饰器运行时机是类定义阶段,不是实例创建阶段,所以第一个参数
target是类的原型(UserService.prototype),不是实例。 - 重写
descriptor.value时,要用普通函数(不要用箭头函数),这样this会自动绑定到调用该方法的实例上。如果用箭头函数,this会指向装饰器所在的上下文(通常是全局),同样拿不到实例属性。
内容的提问来源于stack exchange,提问作者user19280128
相关产品推荐
相关产品推荐

