如何使用bind在添加事件监听器时将类实例作为'this'访问?
如何在事件监听器中用bind绑定类实例作为this?
看起来你是想确保Scroll类实例能在事件处理的各个环节中被正确访问到,尤其是throttle方法和triggered函数里的this指向。下面给你几种实用的方案,结合bind来解决这个问题:
方案1:显式绑定throttle方法的this
虽然你当前用scroll.throttle(...)调用时,throttle内部的this已经指向scroll实例,但如果后续有场景会让throttle的调用上下文丢失(比如把throttle单独提取出来调用),可以用bind提前锁定this:
window.addEventListener('scroll', scroll.throttle.bind(scroll)( triggered, {state: state, wrapper: wrapper, children: children, scroll: scroll}, 50 ));
bind(scroll)会创建一个新的throttle函数副本,确保它执行时this永远指向你的Scroll实例。
方案2:给triggered函数绑定实例this
如果希望triggered内部能直接用this访问Scroll实例(而不是通过o.scroll),可以给triggered绑定实例:
// 绑定triggered的this为scroll实例 window.addEventListener('scroll', scroll.throttle( triggered.bind(scroll), {state: state, wrapper: wrapper, children: children}, 50 ));
这样修改后,triggered里就能直接用this代替o.scroll了:
triggered(o){ if(this.check !== 0){ this.on = false; o.wrapper... // 其他参数依然通过o获取 } }
方案3:在类构造器中提前绑定方法
最稳妥的方式是在Scroll类的constructor里提前绑定所有需要正确this的方法,这样后续任何调用场景都不会丢失上下文:
Scroll = class{ constructor(){ this.on = true; // 提前绑定throttle和triggered的this为当前实例 this.throttle = this.throttle.bind(this); this.triggered = this.triggered.bind(this); } throttle(fn, v, wait){ let time = Date.now(); return () => { if ((time + wait - Date.now()) < 0 && this.on) { fn(v); time = Date.now(); } } } // 把triggered改成类方法,直接用this访问实例属性 triggered(o){ if(this.state.check !== 0){ // 假设state是实例属性 this.on = false; this.wrapper... // 假设wrapper也是实例属性 } } }
之后添加事件监听器就可以简化成:
// 直接传类方法,this已经提前绑定好了 window.addEventListener('scroll', scroll.throttle(scroll.triggered, {state: state, wrapper: wrapper, children: children}, 50));
简单说,bind的核心作用就是创建一个固定了this指向的新函数,不管这个函数在什么上下文里被调用,this都不会变。根据你的实际需求选对应的方案就好~
内容的提问来源于stack exchange,提问作者Himmators
相关产品推荐
相关产品推荐

