JavaScript类中keydown事件修改变量失效问题求助
解决keydown事件修改类变量无反应的问题
嘿,这问题我熟得很——核心原因就是事件处理器里的this指向不对!
先给你拆解一下:当你在构造函数里把this.handler传给addEventListener时,事件触发的那一刻,handler函数里的this已经不再指向你的FPlayer实例了,而是指向触发事件的window对象。你在handler里修改的this.posX其实是window.posX,跟你的类实例半毛钱关系都没有,自然在update方法里看不到变化。而你直接在update里修改时,update是通过实例调用的(比如player.update()),这里的this妥妥指向实例,所以修改就生效了。
给你三种靠谱的修复方案,挑你顺手的用:
方案1:用bind强制绑定this
在构造函数里给handler绑定实例的this,这样不管事件怎么触发,handler里的this都固定指向实例:
class FPlayer { constructor(windowWidth, windowHeight, width, height, posX, posY) { this.width = width; this.height = height; this.posX = posX; this.posY = posY; this.windowWidth = windowWidth; this.windowHeight = windowHeight; this.x = 0; // 关键:用bind把this绑定到handler addEventListener("keydown", this.handler.bind(this)); } handler(e) { if (e.key === 'w') { this.posX += 10; // 现在this指向FPlayer实例了 } } update() { console.log(this.posX); // 可以看到按下w后数值变化了 } }
方案2:用箭头函数定义handler
箭头函数会自动继承外层作用域的this,也就是构造函数里的实例this,完美避开指向问题:
class FPlayer { constructor(windowWidth, windowHeight, width, height, posX, posY) { this.width = width; this.height = height; this.posX = posX; this.posY = posY; this.windowWidth = windowWidth; this.windowHeight = windowHeight; this.x = 0; // 用箭头函数定义handler,自动绑定外层this this.handler = (e) => { if (e.key === 'w') { this.posX += 10; } }; addEventListener("keydown", this.handler); } update() { console.log(this.posX); } }
方案3:在构造函数里保存实例引用
如果习惯用普通函数,也可以在构造函数里把实例存成一个变量(比如self),然后在handler里用这个变量代替this:
class FPlayer { constructor(windowWidth, windowHeight, width, height, posX, posY) { this.width = width; this.height = height; this.posX = posX; this.posY = posY; this.windowWidth = windowWidth; this.windowHeight = windowHeight; this.x = 0; // 保存实例引用 const self = this; this.handler = function(e) { if (e.key === 'w') { self.posX += 10; // 用self访问实例变量 } }; addEventListener("keydown", this.handler); } update() { console.log(this.posX); } }
随便选一种方案改完,按下w键时posX就能正常更新啦!
内容的提问来源于stack exchange,提问作者Teight
相关产品推荐
相关产品推荐

