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

TypeScript转译JS类中setTimeout内this.gates未定义问题求助

问题分析与解决方案

嘿,这个问题我太熟悉了!你遇到的TypeError: this.gates is undefined本质上是JavaScript里经典的this指向绑定问题,我给你拆解下原因和解决办法:

为什么会报错?

当你在run方法里写setTimeout(this.onLoop, 1000)时,你只是把onLoop函数本身作为回调传递给了setTimeout,并没有把它和当前的Simulator实例绑定。等到1秒后setTimeout执行这个函数时,函数内部的this会默认指向全局对象(浏览器环境下是window),而不是你的sim实例,自然就找不到this.gates了。

而你在控制台手动执行sim.onLoop()时,this是明确指向sim实例的,所以能正常访问this.gates——这就是两种场景的核心差异。

三种可行的修复方案

方案1:用箭头函数包裹回调(最简洁直观)

箭头函数不会绑定自己的this,它会继承外层作用域的this(也就是当前的Simulator实例):

run() {
  setTimeout(() => this.onLoop(), 1000);
}

方案2:在构造函数中提前绑定this

在构造函数里把onLoop方法的this绑定到当前实例,这样无论怎么调用onLoop,它的this都指向实例:

class Simulator {
  constructor() {
    this.gates = Array();
    this.gates.push(new AndGate(200, 200));
    // 关键:绑定this到onLoop方法
    this.onLoop = this.onLoop.bind(this);
  }

  // ...其他方法不变
}

方案3:传递回调时直接绑定this

在传给setTimeout的时候,用bind方法把this绑定到当前实例:

run() {
  setTimeout(this.onLoop.bind(this), 1000);
}

修复后的完整代码示例(以方案1为例)

class Simulator {
  constructor() {
    this.gates = Array();
    this.gates.push(new AndGate(200, 200));
  }

  initialize() {
    let canvas = document.getElementById('board');
    canvas.width = 800;
    canvas.height = 500;
    canvas.setAttribute("style", "border: 1px solid black");
    this.gates.push(new AndGate(100, 100));
  }

  run() {
    setTimeout(() => this.onLoop(), 1000);
  }

  onLoop() {
    for (let gate of this.gates) {
      gate.render();
    }
  }
}

let sim = new Simulator();
sim.initialize();
sim.run();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:06:40