如何使用 TypeScript 方法装饰器并保留正常的“this”范围
How to use a TypeScript method decorator and retain normal `this` scope
请注意:此问题是因为在 运行 我的修饰方法中使用了 GraphQL 解析器。这意味着 this
的范围是 undefined
。但是,问题的基础知识对于遇到装饰器问题的任何人都有用。
这是我想使用的基本装饰器(我的有更多代码):
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;
};
};
};
我在装饰器中使用箭头函数,这是我可以将它带到 return 某种范围的唯一方法,尽管不同于正常的 this
范围。
这是我正在使用的 class 和我正在装饰的方法:
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
returned as undefined
.
提前致谢
您问题中的问题似乎是您正在使用箭头函数作为方法,这是不可取的,因为 arrow functions don't get their own this
context。
您接着说更改此设置并不能解决您的问题,但我无法重现:
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() }
我觉得不错。如果您的问题仍然存在,您可能希望在问题中包含有关您的配置的更多详细信息。确保问题中的代码构成 reproducible example 总是有帮助的。祝你好运!
我在使用 class 的方法作为 GraphQL 解析器时遇到了同样的问题,我能够解决该问题的唯一方法是将 class 用作单例,并且然后从单例调用其他私有方法而不是 this.
请注意:此问题是因为在 运行 我的修饰方法中使用了 GraphQL 解析器。这意味着 this
的范围是 undefined
。但是,问题的基础知识对于遇到装饰器问题的任何人都有用。
这是我想使用的基本装饰器(我的有更多代码):
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;
};
};
};
我在装饰器中使用箭头函数,这是我可以将它带到 return 某种范围的唯一方法,尽管不同于正常的 this
范围。
这是我正在使用的 class 和我正在装饰的方法:
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
returned as undefined
.
提前致谢
您问题中的问题似乎是您正在使用箭头函数作为方法,这是不可取的,因为 arrow functions don't get their own this
context。
您接着说更改此设置并不能解决您的问题,但我无法重现:
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() }
我觉得不错。如果您的问题仍然存在,您可能希望在问题中包含有关您的配置的更多详细信息。确保问题中的代码构成 reproducible example 总是有帮助的。祝你好运!
我在使用 class 的方法作为 GraphQL 解析器时遇到了同样的问题,我能够解决该问题的唯一方法是将 class 用作单例,并且然后从单例调用其他私有方法而不是 this.