内部函数不会 return 更改外部函数中分配的变量
Inner function does not return changes to variable assigned in outer function
我正在尝试修改 timeKeyAdditionCheck
函数中的 masterCounter
变量。在timeKeyAdditionCheck
函数内,我成功给masterCounter
赋值,但是这个变化并没有体现在getEventsWithTime
的范围内。当timeKeyAdditionCheck
完成后,masterCounter
的值returns为null。
我需要对 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。
例如,您可以在声明任一函数之前立即声明 masterCounter(假设它们在同一范围内)。
您的声明不正确的标志是检查 masterCounter 是否为空。为了在这些函数之外共享它,当函数尝试访问或设置它时,它永远不能为 null。
因为 masterCounter
没有在 timeKeyAdditionCheck
中声明(它在那里赋值,但没有在那里声明),所以 masterCounter
被隐式声明为全局变量。但是,在 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, range, masterCounter);
checkNewUsers(event, userTracker, masterCounter);
addValidatorsAndEth(event, userTracker, masterCounter);
}
convertToCsv(masterCounter)
console.log(masterCounter)
} catch(error) {
console.log(error);
}
}
此外, 解释了“范围链”并更详细地说明了这个问题。
我没有得到 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()
创建数组中最后一个对象的副本,而不是创建另一个引用。
我正在尝试修改 timeKeyAdditionCheck
函数中的 masterCounter
变量。在timeKeyAdditionCheck
函数内,我成功给masterCounter
赋值,但是这个变化并没有体现在getEventsWithTime
的范围内。当timeKeyAdditionCheck
完成后,masterCounter
的值returns为null。
我需要对 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。
例如,您可以在声明任一函数之前立即声明 masterCounter(假设它们在同一范围内)。
您的声明不正确的标志是检查 masterCounter 是否为空。为了在这些函数之外共享它,当函数尝试访问或设置它时,它永远不能为 null。
因为 masterCounter
没有在 timeKeyAdditionCheck
中声明(它在那里赋值,但没有在那里声明),所以 masterCounter
被隐式声明为全局变量。但是,在 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, range, masterCounter);
checkNewUsers(event, userTracker, masterCounter);
addValidatorsAndEth(event, userTracker, masterCounter);
}
convertToCsv(masterCounter)
console.log(masterCounter)
} catch(error) {
console.log(error);
}
}
此外,
我没有得到 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()
创建数组中最后一个对象的副本,而不是创建另一个引用。