如何解决内部函数不返回对外部函数中分配的变量的更改
我正在尝试在masterCounter
函数中修改timeKeyAdditionCheck
变量。在timeKeyAdditionCheck
函数中,我成功地为masterCounter
分配了一个值,但是此更改未反映在getEventsWithTime
的范围内。 timeKeyAdditionCheck
完成后,masterCounter
的值将返回空。
我需要使用timeKeyAdditionCheck
函数进行哪些更改?
let masterCounter = null;
let userTracker = {};
let timeKeyAdditionCheck = ('hour') => {
assert((range == 'minute' || range == 'hour'),"In calcArrayof... range value needs to equal 'minute' or 'hours'")
if (masterCounter == null) {
masterCounter = [{timerange: event.timestamp,totalusercount: 0,totalvalidatorcount: 0,totaletherdeposited: 0}]
}
if (event.timestamp > (masterCounter[masterCounter.length - 1] + 3599)) {
let differenceInTime = event.timestamp - (masterCounter[masterCounter.length - 1] + 3599);
let timeKeysNeeded = Math.ceil(differenceInTime / 3600);
i = 0;
while (i < timeKeysNeeded) {
let newEntry = masterCounter[masterCounter.length - 1];
newEntry.timerange = newEntry.timerange + 3600;
masterCounter.push(newEntry);
i++;
}
}
}
(async () => {
let events = await getEventsWithTime(3085928,3089928);
for (event of events) {
timeKeyAdditionCheck('hour');
checkNewUsers();
addValidatorsAndEth();
}
convertToCsv(masterCounter)
console.log(masterCounter)
})()
解决方法
由于masterCounter
不在timeKeyAdditionCheck
中声明(在此赋值,但未在此处声明),因此masterCounter
被隐式声明为Global变量。但是,在getEventsWithTime
中,您确实声明了masterCounter
,以便声明“隐藏”全局变量并被视为完全独立的变量。
您需要在比两个函数中的任何一个更高的范围中声明masterCounter
,以便它们都可以访问它,或者您可以将masterCounter
传递给getEventsWithTime
函数,如下所示:一个论点。
// By declaring the variable in a higher scope than either of the functions
// that need access to it,both can find it and use it.
let masterCounter = null // later turns into an array
let timeKeyAdditionCheck = (event,range,masterCounter) => {
assert((range == 'minute' || range == 'hour'),"In calcArrayof... range value needs to equal 'minute' or 'hours'")
if (masterCounter == null) {
masterCounter = [{timerange: event.timestamp,totalusercount: 0,totalvalidatorcount: 0,totaletherdeposited: 0}]
}
if (event.timestamp > (masterCounter[masterCounter.length - 1] + 3599)) {
let differenceInTime = event.timestamp - (masterCounter[masterCounter.length - 1] + 3599);
let timeKeysNeeded = Math.ceil(differenceInTime / 3600);
i = 0;
while (i < timeKeysNeeded) {
let newEntry = masterCounter[masterCounter.length - 1];
newEntry.timerange = newEntry.timerange + 3600;
masterCounter.push(newEntry);
i++;
}
}
}
let getEventsWithTime = async (firstBlock,lastBlock,range) => {
try {
let userTracker = {};
let events = await depositContract.getPastEvents('DepositEvent',{fromBlock: firstBlock,toBlock: lastBlock}) // 2845084 2846000
for (event of events) {
let results = await web3.eth.getBlock(event.blockNumber);
event.timestamp = results.timestamp;
timeKeyAdditionCheck(event,masterCounter);
checkNewUsers(event,userTracker,masterCounter);
addValidatorsAndEth(event,masterCounter);
}
convertToCsv(masterCounter)
console.log(masterCounter)
} catch(error) {
console.log(error);
}
}
还有see this post of mine,它解释了“作用域链”并更详细地说明了此问题。
,您应该在包含要使用它的两个函数的范围内声明masterCounter。
例如,您可以在声明任何一个函数时(假设它们在同一作用域内)在紧前面声明masterCounter。
检查您的声明是否错误的标志是查看masterCounter是否为null。为了在这些功能之外共享它,当该功能尝试访问或设置它时,它永远不能为null。
,之所以没有获得masterCounter
的预期输出,是因为在timeKeyAdditionCheck
函数中,我以为是在masterCounter
数组中复制对象,但实际上我创建了一个参考。这是我的代码中无意间创建引用而不是副本的那一刻:
let newEntry = masterCounter[masterCounter.length - 1];
当我以为在数组中添加唯一对象时,我是在数组末尾添加对该对象的引用。
我使用以下代码对其进行了修复:
while (i < timeKeysNeeded) {
let lastObjectRef = masterCounter[masterCounter.length - 1];
let newEntry = Object.assign({},lastObjectRef)
newEntry.timerange = newEntry.timerange + 60;
masterCounter.push(newEntry);
i++;
}
我使用Object.assign()
来创建数组中最后一个对象的副本,而不是创建另一个引用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。