我有以下方法将命令映射到对象内的函数:
const mapHandler = (str, obj) => {
if (!Reflect.has(obj, str)) {
return null;
}
const candidateHandler = Reflect.get(obj, str, obj);
if (typeof candidateHandler !== "function") {
return null;
}
return candidateHandler;
};
我有一个简单的类,其中包含一些我想使用处理程序调用的命令:
class MyClass {
obj;
constructor() {
this.obj = { a: 1, b: 2 };
}
create() {
return this.obj.a;
}
remove() {
return this.obj.b;
}
}
我设置并运行:
const myobj = new MyClass();
const handler = mapHandler("create", myobj);
console.log("Found", handler);
const res = handler();
但我明白了:
Found [Function: create]
/workspaces/sandbox/index.js:22
return this.obj.a;
^
TypeError: Cannot read properties of undefined (reading 'obj')
at create (/workspaces/sandbox/index.js:22:17)
at Object.<anonymous> (/workspaces/sandbox/index.js:35:13)
at Module._compile (node:internal/modules/cjs/loader:1241:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
at Module.load (node:internal/modules/cjs/loader:1091:32)
at Module._load (node:internal/modules/cjs/loader:938:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
at node:internal/main/run_main_module:23:47
我显然失去了对
this
内部myobj
的引用,很可能是由于Reflect.get
。如何解决此问题并确保处理程序映射器不会导致返回的函数丢失对 this
的引用?
当您引用一个函数时,它不会绑定到任何
this
。您应该使用 Function::call()
进行绑定调用,或者在调用之前使用 Function::bind()
来调用适当的 this
上的函数:
class MyClass {
obj;
constructor() {
this.obj = { a: 1, b: 2 };
}
create() {
return this.obj.a;
}
remove() {
return this.obj.b;
}
}
const mapHandler = (str, obj) => {
if (!Reflect.has(obj, str)) {
return null;
}
const candidateHandler = Reflect.get(obj, str, obj);
if (typeof candidateHandler !== "function") {
return null;
}
// here we bind the func to allow calling without a context
return candidateHandler.bind(obj);
};
const myobj = new MyClass();
const handler = mapHandler("create", myobj);
console.log("Found", handler);
const res = handler();