Tuesday, May 14, 2024
68
rated 0 times [  70] [ 2]  / answers: 1 / hits: 11893  / 6 Years ago, tue, november 27, 2018, 12:00:00

When I bind a function with the parent this passed in thisArg, I can't unbind the same named function expression, but without it I can unbind the function itself. Why is that?



This works:



choicesList.addEventListener(click, function() {

const self= this;

document.addEventListener(click, function checkClick(e) {

if (!e) e = event;
if (!self.contains(e.target)) {

document.removeEventListener(click, checkClick);
}
}, false);
});


This doesn't:



choicesList.addEventListener(click, function() {

document.addEventListener(click, function checkClick(e) {

if (!e) e = event;
if (!this.contains(e.target)) {
document.removeEventListener(click, checkClick);
}
}.bind(this), false);
});

More From » javascript-objects

 Answers
1

The reason for this is issue is that calling bind() on a function returns a new instance of that function:





function someHandler() {
alert('hi');
}

const someHandlerBinded = someHandler.bind(document);


// Returns false, seeing as these are different instances of the function
console.log( someHandlerBinded === someHandler );





By setting an event handler directly, via the result of bind() as you are in your second block of code, this causes a new instance of that function handler to be passed to addEventListener(). This in turn means that the subsequent attempt to removing this handler on line:



document.removeEventListener(click, checkClick);


will fail, seeing that the the defined function checkClick is not the same as the actual handler function used for that click event (ie the new function instance returned from function checkClick(){ ... }.bind())



One way to resolve this might be the following:



choicesList.addEventListener(click, function() {

// Declare the bound version of the click handler
const boundClickHandler = function checkClick(e) {

if (!e) e = event;

if (!this.contains(e.target)) {

// Removing the result of bind, rather than the declared
// checkClick handler
document.removeEventListener(click, boundClickHandler);
}
}.bind(this)

// Adding the result of bind as you currently are doing
document.addEventListener(click, boundClickHandler, false);
});

[#10130] Saturday, November 24, 2018, 6 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
mckenna

Total Points: 445
Total Questions: 109
Total Answers: 109

Location: Virgin Islands (U.S.)
Member since Sun, May 16, 2021
3 Years ago
;