【发布时间】:2020-09-22 02:48:23
【问题描述】:
我想在 Typescript 装饰器和 reflect-metadata 的帮助下创建一个抽象。但是当我调用传入元数据的函数时,this 是未定义的:
import "reflect-metadata";
const METHODS = "__methods__";
const Method = (obj: object) => {
return function MethodDecorator(
target: object,
methodName: string | symbol,
descriptor: PropertyDescriptor
) {
const metadata = Reflect.getMetadata(METHODS, obj);
Reflect.defineMetadata(
METHODS,
{ ...metadata, [methodName]: descriptor.value },
obj
);
};
};
const someObject: object = new Object();
class Main {
private num = 42;
constructor(other: Other) {
other.init(someObject);
}
@Method(someObject)
myMethod() {
console.log("hello");
console.log(this.num); // this is undefined (how can I fix it?)
}
}
class Other {
private methods: Record<string, Function> = {};
init(obj: object) {
this.methods = Reflect.getMetadata(METHODS, obj);
}
trigger(methodName: string) {
this.methods[methodName]();
}
}
const other = new Other();
new Main(other);
other.trigger("myMethod");
上面代码sn-p的输出是
hello
undefined
为什么this 未定义,我该如何解决?
您可以通过克隆 this 示例 repo 并运行来自己尝试
yarn install
yarn start
【问题讨论】:
-
你试过
.bind()吗?myMethod() { ... }.bind(this) -
@Ifaruki 我想过这个问题。但我不确定在我的示例中如何做到这一点,因为我在
MethodDecorator中没有对this的引用。也许在target的帮助下? -
嗯,你只是把
this.num =4;放在你的构造函数中吗? -
@Ifaruki 这只是一个例子。在我的真实用例中,有在运行时分配的值
-
我不完全理解你的问题,但我知道这一点:你可以用这样的自定义调用函数:
myfunc.call(this)或者,我认为更有可能的解决方案是 ES6箭头函数实际上修改了我们习惯的this关键字。尝试使用普通函数而不是箭头函数。
标签: typescript reflect-metadata