bind绑定函数this失效?箭头函数回调内this指向window无法移除事件监听器
问题原因
- 箭头函数的this指向无法通过
bind修改:箭头函数的this在定义阶段就绑定到外层作用域,不受call/apply/bind调用影响,也不会随执行上下文变化。你定义checkTable时使用了箭头函数,外层作用域为全局,因此this固定指向window,bind操作完全无效。 - 存在拼写错误:绑定时传入的
checlBtn为笔误,正确变量名为checkBtn。 - 移除监听的函数引用不匹配:
bind执行后会返回一个全新的函数实例,你调用addEventListener时传入的是bind生成的新函数,但调用removeEventListener时传入的是原始的checkTable函数,二者引用不一致,无法完成监听移除。
修复方案
方案1:改为普通函数配合bind使用
将监听函数改为普通函数,同时保存bind生成的函数引用,保证移除监听时引用一致:
// 替换为普通函数,支持动态修改this指向 function checkTable() { this.removeEventListener('click', this.boundCheckTable); console.log(this); // 正确输出按钮DOM元素 setTimeout(() => { // 原有业务逻辑 // 若需要计时结束后恢复点击监听,可在此处补加: // this.addEventListener('click', this.boundCheckTable); }, 3000); }; const app = () => { const checkBtn = document.querySelector('.check-btn'); // 保存bind生成的函数实例,挂载到按钮元素上方便后续取用 checkBtn.boundCheckTable = checkTable.bind(checkBtn); checkBtn.addEventListener('click', checkBtn.boundCheckTable); }; app();
方案2:通过事件对象获取触发元素(更简洁)
直接通过事件参数的currentTarget属性拿到触发事件的按钮元素,不需要处理this绑定逻辑:
const checkTable = (e) => { const checkBtn = e.currentTarget; checkBtn.removeEventListener('click', checkTable); console.log(checkBtn); // 正确输出按钮DOM元素 setTimeout(() => { // 原有业务逻辑 }, 3000); }; const app = () => { const checkBtn = document.querySelector('.check-btn'); checkBtn.addEventListener('click', checkTable); }; app();
内容的提问来源于stack exchange,提问作者Geindzo
相关产品推荐
相关产品推荐

