clearInterval() 如何清除 setInterval() 中的 timerID?

How clearInterval() clears a timerID inside of a setInterval()?

我是 Javascript 的新手,刚接触到堆栈这个话题。在下面的一段代码中(为了专注于基础而不是语法,这段代码很简单),我可以清除函数表达式变量中的 timerID。这样做很常见,但我的问题是这里的堆栈是如何制作的?说得更清楚一点,事物的秩序如何继续下去,清除者本身所处的变量呢?以及如何在 clearInterval() 之后调用 "console.log('DONE!')"?


function countNumbers(number){
  var timer = setInterval(function(){
    number++;
    if(number >= 10){
      clearInterval(timer);
      console.log('DONE!');
    }
    else {
      console.log(number);
    }

  },1000)
}

当内部函数在JavaScript中维护对外部函数变量的引用时,形成clousure,即外部函数的成员是当外部函数完成时不会被销毁 运行ning 因为它的变量仍然被另一个函数引用。

这是因为当执行一个函数时,会为该函数的环境创建一个新的执行上下文。它维护着一个作用域链,然后按执行顺序被压入执行栈。

有全局执行上下文,然后countNumbers的调用创建自己的执行上下文,最后创建回调的执行上下文。回调函数执行上下文维护一个指向 countNumbers 函数执行上下文范围的指针,它维护一个指向全局执行上下文的指针:

在您的情况下,当 setInterval() 运行 是 immediately/synchronously returns ID 并且它设置在 timer 变量中。由于 timer 变量是在 countNumbers 函数的范围内定义的,因此 inner/callback 函数对其形成了一个闭包。回调的执行上下文可以通过作用域链到达并访问timer变量。

现在,当您 运行 setInterval 时,回调会按指定的时间间隔异步排队和执行。由于之前形成的闭包,回调可以访问在外部函数作用域中声明的 timer 变量,因此当 number 达到 10 时,它可以使用外部函数作用域中的 ID 值来取消间隔。