You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何调用clock.stop()无法终止clock.start()启动的定时器?

定时器无法停止的原因与修复方案

你碰到的这个问题其实很常见,核心是**setTimeout回调里的this指向不对**,导致你调用clearInterval(this._timer)时,根本没拿到正确的定时器ID,所以定时器才会继续跑。

问题根源拆解

在你的stop方法里,setTimeout的回调函数执行时,默认情况下this指向的是全局对象(浏览器环境里就是window),而不是你的Clock实例对象。所以这里的this._timer其实是undefined,调用clearInterval(undefined)完全起不到终止定时器的作用——这就是为什么你能看到Stop!的日志,但定时器还在运行的原因。

三种修复方案

你可以用以下任意一种方式来修正this的指向:

1. 提前保存this到变量(和start方法的写法一致)

这是最传统也最稳妥的方式,把当前实例的this存到一个变量里,在回调里用这个变量访问实例:

Clock.prototype.stop = function() {
  var self = this; // 保存当前Clock实例的引用
  setTimeout(function() {
    clearInterval(self._timer);
    console.log('Stop!');
  }, 5000);
};

2. 使用箭头函数(ES6+)

箭头函数不会创建自己的this,它会继承外层作用域的this,也就是stop方法执行时的Clock实例:

Clock.prototype.stop = function() {
  setTimeout(() => {
    clearInterval(this._timer);
    console.log('Stop!');
  }, 5000);
};

3. 用bind绑定this

通过bind方法把回调函数的this绑定为当前的Clock实例:

Clock.prototype.stop = function() {
  setTimeout(function() {
    clearInterval(this._timer);
    console.log('Stop!');
  }.bind(this), 5000);
};

验证效果

把上面任意一种方案替换原有的stop方法后,5秒后clearInterval就能正确拿到start方法里保存的定时器ID,从而成功终止定时器。

内容的提问来源于stack exchange,提问作者Sviat Kuzhelev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:36:39