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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:35:51