【发布时间】:2015-09-29 22:41:43
【问题描述】:
我有以下函数 makeStopwatch,我正在尝试通过它来更好地理解 javascript 闭包:
var makeStopwatch = function() {
var elapsed = 0;
var stopwatch = function() {
return elapsed;
};
var increase = function() {
elapsed++;
};
setInterval(increase, 1000);
return stopwatch;
};
var stopwatch1 = makeStopwatch();
var stopwatch2 = makeStopwatch();
console.log(stopwatch1());
console.log(stopwatch2());
当我console.log 调用stopwatch1 和stopwatch2 时,我每次都分别返回0。
据我了解makeStopwatch 的预期功能,如果由内部函数stopwatch 返回,变量elapsed 将是0。内部函数increase 递增变量elapsed。然后 setInterval 在延迟 1 秒后调用 increase。最后,这次再次返回stopwatch,更新后的值预计为1。
但这不起作用,因为在makeStopwatch 内部,内部stopwatch、increase 和setInterval 函数都在彼此独立的范围内?
我如何修改它以使其工作,以便 elapsed 递增并且该值被关闭并保存,以便当我将 makeStopwatch 分配给变量 stopwatch1 并调用 stopwatch1 时更新的值被退回?
【问题讨论】:
-
您的代码正在运行。另外,CodeSchool? (我将您的代码完全按照您的方式放入控制台。多次运行
console.log(stopwatch1())。) -
发布的代码将始终为两者记录 0,因为 console.log 将在创建秒表的 1 秒内发生。例如,尝试将底部两行包裹在
setTimeout(console.log(stopwatch1()), 2000);setTimeout(console.log(stopwatch2()), 4000);中,以查看秒表确实“正在运行” -
我想我很困惑,因为查看函数体
increase以及elapsed是如何递增的,以及我对现实世界秒表功能的看法,我希望console.logs 显示秒表确实在向上计数。 -
在您的原始代码中,您是控制台日志记录一次,就在创建秒表时,您当然会得到一个零 - elapsed 的值被初始化为零,因此它的输出为零 - 之后一秒钟,它将是 1,两秒钟后它将是 2,依此类推
-
@phizzy @Jaromanda 的代码错误:应该是
setTimeout(function() {console.log(stopwatch1())}, 2000);和stopwatch2相同。
标签: javascript scope closures