在addEventListener中引用对象this的最专业方式是什么?
解决康威生命游戏中事件监听的
this指向问题 你遇到的是JS中事件处理器this绑定的典型问题——事件触发时,回调函数里的this默认指向触发事件的DOM元素,而非你的构造函数实例。下面是几种更专业的解决方案:
1. 使用bind()固定this指向
Function.prototype.bind()会返回一个新函数,强制将函数内部的this绑定到你指定的对象上。在构造函数中绑定事件时,直接把实例的this传给bind即可:
// 在构造函数的事件绑定代码中 cell.addEventListener('click', this.toggleState.bind(this));
这样不管事件触发时的上下文是什么,toggleState里的this都会指向你的生命游戏模拟器实例。
2. 用箭头函数作为包装层
你之前尝试箭头函数没解决问题,应该是直接传了this.toggleState——正确的做法是用箭头函数包裹回调,利用箭头函数的词法作用域特性,它的this会继承自外层构造函数的上下文:
cell.addEventListener('click', (event) => { this.toggleState(event); });
箭头函数没有自己的this,内部的this就是构造函数里的实例,完美解决指向问题。如果逻辑简单,还可以写成一行:
cell.addEventListener('click', (e) => this.toggleState(e));
3. 在构造函数中预先绑定方法
如果你的模拟器有大量单元格需要绑定事件,每次都用bind会生成多个新函数,有点浪费。可以在构造函数开头就把原型方法的this绑定到实例:
function GameOfLife() { // 预先绑定方法的this到实例 this.toggleState = this.toggleState.bind(this); // 后续绑定事件直接传this.toggleState即可 cells.forEach(cell => { cell.addEventListener('click', this.toggleState); }); } GameOfLife.prototype.toggleState = function(event) { // 这里的this就是GameOfLife实例 const cell = event.target; // 执行切换状态逻辑 };
这种方式只需要绑定一次,后续所有事件监听都能直接复用绑定好的方法。
关于你用临时变量的写法
其实你一开始用myBackupThis = this的写法完全没问题,这是ES6之前很常用的“保存上下文”技巧,业内常叫它that或者self(比如const self = this;),并不是不专业——只是ES6之后有了更简洁的bind和箭头函数,才慢慢被替代而已。
内容的提问来源于stack exchange,提问作者joe
相关产品推荐
相关产品推荐

