如何在javascript中使用闭包访问函数内另一个作用域中的变量?

如何在javascript中使用闭包访问函数内另一个作用域中的变量?,javascript,scope,closures,Javascript,Scope,Closures,为了更好地理解javascript闭包,我尝试使用以下函数makeStopwatch: var makeStopwatch = function() { var elapsed = 0; var stopwatch = function() { return elapsed; }; var increase = function() { elapsed++; }; setInterval(increase, 1000); return stopwat

为了更好地理解javascript闭包,我尝试使用以下函数
makeStopwatch

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
返回变量
appead
,则变量
0
。内部函数
递增
递增变量
经过的时间
。然后
setInterval
在延迟1秒后调用
rease
。最后,
stopwatch
再次返回,更新后的值应为
1

但这不起作用,因为内部
makeStopwatch
、内部
stopwatch
increase
setInterval
函数都在彼此独立的范围内

根据我的理解,我如何修改它以使
已用时间
增加,并关闭和保存该值,以便在我将
makeStopwatch
分配给变量
stopwatch1
并调用
stopwatch1
时返回更新的值

var makeStopwatch = function() {
  var elapsed = 0;

  // THIS stopwatch function is referenced later
  var stopwatch = function() {
    return elapsed;
  };

  var increase = function() {
    elapsed++;
  };
  // This setInterval will continue running and calling the increase function.
  // we do not maintain access to it.
  setInterval(increase, 1000);

  // THIS returns the stopwatch function reference earlier.  The only way
  // we can interact with the closure variables are through this function.
  return stopwatch;
};

var stopwatch1 = makeStopwatch();
// This runs the makeStopwatch function.  That function *RETURNS* the
// inner stopwatch function that I emphasized above.

console.log(stopwatch1());
// stopwatch1 is a reference to the inner stopwatch function.  We no longer
// have access to the elapsed variable or the function increase.  However
// the `setInterval` that is calling `increase` is still running.  So every
// 1000ms (1 second) we increment elapsed by 1.

因此,如果我们将上述所有代码放入控制台,然后偶尔调用
console.log(stopwatch1())
,它将console.log记录创建秒表后的秒数。

您的代码正在工作。还有,学校?(我将您的代码完全按照您的方式放入控制台。多次运行
console.log(stopwatch1())
)。由于console.log将在创建秒表的1秒内出现,因此发布的代码将始终为这两种代码记录0。尝试将底部的两行包装在
setTimeout(console.log(stopwatch1()),2000)中设置超时(console.log(stopwatch2()),4000)例如,要看到秒表确实在“运行”,我想我会感到困惑,因为查看函数体
增加
,以及
已用时间
如何增加,以及考虑到我对现实世界秒表的感知,我希望console.logs显示秒表确实在向上计数。在您的原始代码中,您在控制台上记录了一次,就在秒表创建时,您当然会得到一个零-经过的值初始化为零,因此它的输出为零-一秒钟后,它将为1,两秒钟后会是2秒左右on@phizzy@Jaromanda的代码错误:应该是
setTimeout(function(){console.log(stopwatch1())},2000)和秒表2的代码相同。