严格模式下如何让绑定的事件监听函数引用自身?
解决方案:在严格模式下让绑定后的事件回调引用自身
这确实是个很典型的问题——当你用bind()生成绑定函数后,原函数和绑定后的函数是完全独立的引用,再加上严格模式下arguments.callee被禁用,直接在回调里用原函数去移除监听肯定无效。下面给你几个可行的解决思路:
1. 利用闭包保存绑定函数的引用
这是最直观的方法,在创建绑定函数的作用域里用变量保存它,然后回调内部通过闭包访问这个变量:
function foo () { // 先声明变量,让回调可以引用到 let boundCallback; // 定义并赋值绑定后的函数,内部直接使用boundCallback boundCallback = function(boundParam, event) { // 这里可以正确移除绑定后的函数 eventBus.removeListener(boundCallback); // 你的业务逻辑 console.log('处理事件,参数:', boundParam); }.bind({}, 7); eventBus.addListener(boundCallback); }
原理:boundCallback在foo的作用域里被声明,回调函数通过闭包可以访问到这个变量,即使经过bind()创建了新函数,内部依然能拿到正确的绑定函数引用。
2. 使用命名函数表达式(严格模式友好)
严格模式允许命名函数表达式的内部引用自己的名字,而且这个名字不会污染外部作用域。你可以把绑定逻辑和命名表达式结合起来:
function foo () { const boundCallback = (function self(boundParam, event) { // 直接引用外部的boundCallback变量完成移除 eventBus.removeListener(boundCallback); }).bind({}, 7); eventBus.addListener(boundCallback); }
或者更简洁的写法,本质还是利用闭包特性:
function foo () { const boundCallback = function(boundParam, event) { eventBus.removeListener(boundCallback); }.bind({}, 7); eventBus.addListener(boundCallback); }
3. 用箭头函数替代bind(简化写法)
如果你的绑定需求只是固定参数,不需要修改this指向,用箭头函数会更简洁,而且天然支持闭包引用自身:
function foo () { const boundCallback = (event) => { // 直接引用自身完成移除 eventBus.removeListener(boundCallback); // 固定参数7直接写在内部 console.log('处理事件,固定参数:7'); }; eventBus.addListener(boundCallback); }
这种方案代码更简洁,适合不需要动态绑定this和参数的场景。
4. 给绑定函数添加自定义属性
如果你必须保留原函数的结构,可以给绑定后的函数添加一个指向自身的属性,然后在回调里通过这个属性访问:
function callback(boundParam, event) { // 通过自定义属性拿到绑定后的函数 eventBus.removeListener(this.boundSelf); } function foo () { const boundCallback = callback.bind({}, 7); // 给绑定函数添加属性指向自身 boundCallback.boundSelf = boundCallback; eventBus.addListener(boundCallback); }
如果希望回调里的this直接指向绑定函数,可以调整绑定的this参数:
function callback(boundParam, event) { // 此时this就是绑定后的函数本身 eventBus.removeListener(this); } function foo () { const boundCallback = callback.bind(boundCallback, 7); eventBus.addListener(boundCallback); }
这个方案适合需要复用原回调函数的场景,通过自定义属性来传递绑定函数的引用。
内容的提问来源于stack exchange,提问作者medihack
相关产品推荐
相关产品推荐

