关闭变量未定义:如何在JS中访问外部变量?

时间:2019-03-25 18:19:11

标签: javascript scope closures wrapper

我有一个事件侦听器,该事件侦听器通过回调进行响应。
此回调是实际回调的包装。
我已经在最外层的函数blockNumber中定义了一个变量,并想从最内层的函数访问(读/写)。

代码如下。

startWeb3 = async () => { 
  await initWeb3();

  var blockNumber = await web3.eth.getBlockNumber();
  console.log(blockNumber) //=> "184"

  window.KYCinstance.events.ReportedFraudA({ fromBlock:0 }, 
  (error, event) => {
    console.log(blockNumber); //=> "184"
    listenCallback(error, event, "fromFraudEvents");
  });

listenCallback = async (error, event, type) => {
  if (error) { console.log(error); }
  else {
    console.log(blockNumber); //=> "ERROR"
  }
}

结果是一条错误消息,当然,如果我执行this.blockNumber,则它是未定义的变量。

startWeb3是最重要的功能,
它有一个事件监听器,它调用listenCallback
它是在此回调内部,我试图返回最外层范围。

1 个答案:

答案 0 :(得分:-1)

根据MDN定义

  

闭包是函数和词法环境的组合   在其中声明了该函数。

因此,按照上述定义,listenCallback在声明自身时在其词法范围内没有声明。 listenWrapperFromlistenCallback将在其闭包中声明它们的位置而不是引用它们的位置接收变量。

为了解决这个问题,您可以在listenCallbackFromlistenCallback方法的词法范围内定义blockNumber

var blockNumber;

listenToEvent = async () => { 

  blockNumber = await web3.eth.getBlockNumber();

  KYCinstance.events.ReportedFraudA({ fromBlock:0 }, listenWrapperFrom); 

};

function listenWrapperFrom(error, event) {
  listenCallback(error, event, "fromFraudEvents");
}

async function listenCallback (error, event, type) {
  if (error) { console.log(error); }
  else {
    console.log(blockNumber);
    let value = await someFunction();
  }
}