调用 Reflect.get 时丢失对“this”的引用

问题描述 投票:0回答:1

我有以下方法将命令映射到对象内的函数:

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
的引用?

javascript this
1个回答
0
投票

当您引用一个函数时,它不会绑定到任何

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

© www.soinside.com 2019 - 2024. All rights reserved.