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
相关产品推荐
相关产品推荐

