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

运行setInterval时无法更新类内部对象属性的问题求助

问题原因

报错的核心是setInterval回调里的this指向错误:

  • 你给setInterval传入的是普通匿名函数,普通函数的this是运行时动态绑定的,在定时器回调执行时,this默认指向全局对象(浏览器环境为window,Node环境为globalThis)
  • 全局对象上不存在_keys属性,所以this._keys取值为undefined,尝试给undefined设置forward属性就抛出了对应的错误。
    原来写在_Init方法顶层的判断逻辑没有报错,是因为顶层代码的this指向类实例本身,能正常访问到this._keys。
解决方案

下面提供3种可直接落地的修复方式:

方案1:使用箭头函数作为回调(最简洁推荐)

箭头函数不会创建自己的this,会继承定义位置外层上下文的this,刚好可以拿到类实例的指向:

// 把原来的setInterval普通函数改成箭头函数即可
setInterval(() => {
  if (currentKeylogW == '"w"') {
    this._keys.forward = true;
  } else if (currentKeylogA == '"a"') {
    this._keys.left = true;
  } else if (currentKeylogD == '"d"') {
    this._keys.left = true;
  } else if (currentKeylogS == '"s"') {
    this._keys.right = true;
  } else if (currentKeylogW == '"!w"') {
    this._keys.forward = false;
  } else if (currentKeylogA == '"!a"') {
    this._keys.left = false;
  } else if (currentKeylogD == '"!d"') {
    this._keys.left = false;
  } else if (currentKeylogS == '"!s"') {
    this._keys.right = false;
  }
}, 500)

方案2:提前缓存this指向

在定时器外把类实例的this存到临时变量中,回调里直接用临时变量访问实例属性:

// 在setInterval前加一行缓存this
const _this = this;
setInterval(function() {
  // 所有this换成_this即可
  if (currentKeylogW == '"w"') {
    _this._keys.forward = true;
  } else if (currentKeylogA == '"a"') {
    _this._keys.left = true;
  } else if (currentKeylogD == '"d"') {
    _this._keys.left = true;
  } else if (currentKeylogS == '"s"') {
    _this._keys.right = true;
  } else if (currentKeylogW == '"!w"') {
    _this._keys.forward = false;
  } else if (currentKeylogA == '"!a"') {
    _this._keys.left = false;
  } else if (currentKeylogD == '"!d"') {
    _this._keys.left = false;
  } else if (currentKeylogS == '"!s"') {
    _this._keys.right = false;
  }
}, 500)

方案3:用bind绑定this指向

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

setInterval(function() {
  // 内部逻辑完全不用改
  if (currentKeylogW == '"w"') {
    this._keys.forward = true;
  } else if (currentKeylogA == '"a"') {
    this._keys.left = true;
  } else if (currentKeylogD == '"d"') {
    this._keys.left = true;
  } else if (currentKeylogS == '"s"') {
    this._keys.right = true;
  } else if (currentKeylogW == '"!w"') {
    this._keys.forward = false;
  } else if (currentKeylogA == '"!a"') {
    this._keys.left = false;
  } else if (currentKeylogD == '"!d"') {
    this._keys.left = false;
  } else if (currentKeylogS == '"!s"') {
    this._keys.right = false;
  }
}.bind(this), 500) // 末尾加.bind(this)绑定上下文
可选优化建议

你当前的多分支if else判断可以简化,后续维护更方便:

setInterval(() => {
  this._keys.forward = currentKeylogW === '"w"';
  this._keys.left = currentKeylogA === '"a"' || currentKeylogD === '"d"';
  this._keys.right = currentKeylogS === '"s"';
}, 500)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:24:04