I have the following code that defines a class for input events management: mouse, touch, pointer, ...
// base.js
export default () => {
return {
el: undefined,
event: undefined,
handler(ev) {
console.log('default handler')
},
attach() {
el.addEventListener(event, this.handler.bind(this), false)
},
detach() {
el.removeEventListener(event, this.handler.bind(this), false)
}
}
}
// mouse.js
import baseInput from './base'
export default (el) => {
return Object.assign(Object.create(baseInput()), {
el: undefined,
event: 'mousedown',
handler(ev) {
console.log('mouse handler)
}
}
}
There's some common business logic in 'base' object.
The problem comes from the calls to this.handler.bind(this) in attach and detach functions, because the returned bound function is not the same for each call, so removeEventListener can't remove the event listener added by addEventListener.
I know I have to keep one single function reference. My question is where that code should be.
One solution may be:
// base.js
export default () => {
let boundFunction;
return {
el: undefined,
event: undefined,
getBoundFunction() {
if (!boundFunction) {
boundFunction = this.handler.bind(this)
}
},
handler(ev) {
console.log('default handler')
},
attach() {
el.addEventListener(event, this.getBoundFunction(), false)
},
detach() {
el.removeEventListener(event, this.getBoundFunction(), false)
}
}
}
This code works, but I don't want that extra getBoundFunction call for each event triggered and I think there should be a better method or best practice.
mouse.js, you have two consecutivereturnstatements.this.handler = this.handler.bind(this)) is to use constructors andnew. Of course you could do the same and just bind your handler method the factory function.