10

请注意:这个问题是因为在运行我的装饰方法时使用了 GraphQL 解析器。这意味着 的范围thisundefined。但是,该问题的基础知识对于遇到装饰器问题的任何人都很有用。


这是我想要使用的基本装饰器(我的有更多代码):

const someDecorator = (argPassed: any) => {

  return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {

    const originalMethod = descriptor.value;

    // DO stuff here...
    console.log(argPassed);

    // Wrapping the original method
    descriptor.value = (...args: any[]) => {

      const result = originalMethod.apply(this, args);

      return result;
    };
  };
};

我在装饰器中使用箭头函数,这是我可以让它返回某种范围的唯一方法,尽管它与普通this范围不同。

这是我正在使用的类和我正在装饰的方法:

class SomeClass {

  constructor() {
  }

  @someDecorator('Passing this in...')
  public doingSomething(argPassed: string) {

    console.log(this); // Returns: { default: SomeClass { otherMethodInMyClass: [Function] } }

    //  Meaning i can't do this
    //  this.otherMethodInMyClass is not a function
    this.otherMethodInMyClass(argPassed);

  }

  private otherMethodInMyClass = (argPassed: any) => {
    // Let's go for it...
  }

}

目前,装饰器将范围传回doingSomething为:

{ default: SomeClass { otherMethodInMyClass: [Function] } }

当不使用装饰器时,我得到:

SomeClass { doingSomething: [Function], otherMethodInMyClass: [Function] }

这是正常行为吗?如果没有,我做错了什么?如果是这样,我如何允许我的方法在调用其他方法之后使用它自己的范围。

更新:正如@jcalz 正确提到的,箭头函数没有自己的this上下文。但是,当我在装饰器中使用非箭头函数时,this返回为undefined.

提前致谢

4

2 回答 2

16

您问题中的问题似乎是您使用箭头函数作为一种方法,这是不可取的,因为箭头函数没有自己的this上下文

你接着说改变这个并不能解决你的问题,但我无法重现:

const someDecorator = (argPassed: any) => {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        const originalMethod = descriptor.value;
        console.log("ARGPASSED: ");
        console.log(argPassed);
        // anonymous function, not arrow
        descriptor.value = function (...args: any[]) {
            const result = originalMethod.apply(this, args);
            return result;
        };
    };
};

class SomeClass {    
    constructor() { }

    @someDecorator('Passing this in...')
    public doingSomething(argPassed: string) {   
        console.log("THIS: ")
        console.log(this); 
        this.otherMethodInMyClass(argPassed);
    }

    private otherMethodInMyClass = (argPassed: any) => { }
}

new SomeClass().doingSomething("abc");
// ARGPASSED: 
// Passing this in...
// THIS: 
// Object { otherMethodInMyClass: otherMethodInMyClass() }

链接到 Playground 中的代码

对我来说看上去很好。如果您的问题仍然存在,您可能希望在问题中包含有关您的配置的更多详细信息。确保问题中的代码构成可重现的示例总是有帮助的。祝你好运!

于 2019-05-17T16:04:31.280 回答
0

当使用类的方法作为 GraphQL 解析器时,我遇到了同样的问题,我能够解决这个问题的唯一方法是将类用作单例,然后从单例而不是this调用其他私有方法。

于 2019-10-07T20:26:47.963 回答