setInterval调用类render方法时this指向window而非实例该如何解决
问题原因
把类方法直接作为参数传给setInterval时,仅传递了函数本身的引用,函数执行时失去了实例上下文绑定,this默认指向全局window对象,导致无法访问this.sprites等实例属性。
可行解决方案
以下3种方案改造成本低,且完全兼容多实例需求:
- 方案1:
setInterval调用处用箭头函数包装(改造成本最低)
箭头函数的this继承自定义位置的上下文,此处刚好指向当前类实例,无需额外绑定:
setRenderInterval(fps) { return setInterval(() => this.render(), 1000/fps); }
- 方案2:用
bind显式绑定实例上下文
提前将render方法的this绑定到当前实例,再传给setInterval即可:
setRenderInterval(fps) { return setInterval(this.render.bind(this), 1000/fps); }
- 方案3:将render定义为类字段箭头函数
直接把render方法改造成箭头函数形式,它的this会永久绑定到所属实例,后续任意场景调用都不会出现指向问题:
class gameController extends instance { constructor(name="untitled") { super(name); this.camera = null; this.rendering = {"FPS":0,"cnv":null,"ctx":null} this.sprites = []; this.data.renderFrame = 0; } // 改造成箭头函数类字段 render = () => { drawRect(0,0,canvas.width,canvas.height,3); for (let i = 0; i < this.sprites.length; i++) { if (this.sprites[i]) { let cs = this.sprites[i] cs.drawRoutine(cs.position.x,cs.position.y); } } } setRenderInterval(fps) { return setInterval(this.render,1000/fps); } }
补充优化建议
原代码中render方法的循环条件i <= this.sprites.length存在越界风险,数组下标范围是0 ~ length-1,建议改为i < this.sprites.length,减少不必要的判断逻辑。
内容的提问来源于stack exchange,提问作者Vercte
相关产品推荐
相关产品推荐

