简体   繁体   English

如何使用TypeScript方法修饰符并保留正常的`this`范围

[英]How to use a TypeScript method decorator and retain normal `this` scope

PLEASE NOTE: This issue was because of the use of GraphQL resolvers in running my decorated method. 请注意:此问题是由于在运行我的修饰方法时使用了GraphQL解析器。 It meant that the scope of this was undefined . 这意味着,范围thisundefined However, the basics of the question are useful for anyone hitting a problem with decorators. 但是,该问题的基础知识对于任何使用装饰器遇到问题的人都是有用的。


This is a basic decorator I'm wanting to use (mine has more code in it): 这是我要使用的基本装饰器(我的装饰器中有更多代码):

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;
    };
  };
};

I am using arrow functions within the decorator which is the only way i could get it to return some kind of scope, albeit different to a normal this scope. 我正在装饰器中使用箭头函数,这是我可以使其返回某种范围的唯一方法,尽管与正常的this范围有所不同。

This is the class I'm using and the method I'm decorating: 这是我正在使用的类以及我正在装饰的方法:

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...
  }

}

Currently the decorator passes back the scope of doingSomething as: 当前,装饰器将doingSomething的范围传递回为:

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

When not using the decorator I get: 当不使用装饰器时,我得到:

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

Is this normal behaviour? 这是正常行为吗? If not, what am I doing wrong? 如果没有,我在做什么错? If so, how do I allow my method to use its own scope as I am calling other methods after. 如果是这样,我该如何允许我的方法在随后调用其他方法时使用其自己的范围。

Update: As @jcalz rightly mentioned, an arrow function doesn't get its own this context. 更新:由于@jcalz正确地提到,箭头的功能没有得到自己的this方面。 However when I used a non-arrow function across the decorator this returned as undefined . 但是,当我在装饰器上使用非箭头函数时, this函数返回undefined

Thanks in advance 提前致谢

The issue in your question seems to be that you're using an arrow function as a method, which is not advisable since arrow functions don't get their own this context . 您问题中的问题似乎是您使用了箭头函数作为方法,因此不建议这样做,因为箭头函数没有this上下文

You went on to say that changing this doesn't fix your issue, but I can't reproduce that: 您继续说,更改此设置不能解决您的问题,但是我无法重现此问题:

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() }

Link to code in Playground 链接到Playground中的代码

Looks good to me. 对我来说看上去很好。 If your issue persists, you might want to include more details about your configuration in your question. 如果问题仍然存在,则可能要在问题中包括有关配置的更多详细信息。 It always helps to make sure that code in your questions constitutes a reproducible example . 始终可以确保问题中的代码构成可重现的示例 Good luck! 祝好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM