最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript: Bindunbind function behavior - Stack Overflow

programmeradmin2浏览0评论

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);
});

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);
});
Share Improve this question edited Nov 27, 2018 at 2:29 Dacre Denny 30.4k5 gold badges51 silver badges66 bronze badges asked Nov 27, 2018 at 2:10 Rick StanleyRick Stanley 8502 gold badges13 silver badges25 bronze badges 3
  • I do can unbind ????? – Scott Marcus Commented Nov 27, 2018 at 2:12
  • it's because the declared checkClick function !== the function resulting from checkClick(){}.bind(this), which means removeEventListener() fails to find a match – Dacre Denny Commented Nov 27, 2018 at 2:13
  • 1 note that Function.bind() !== Function.bind(). Every call to .bind creates another object or function (your second example checkClick.bind(this) !== checkClick). In order to remove an event listener you MUST pass in the same object (function) and options used to create the event listener. – Jay Harris Commented Nov 27, 2018 at 2:26
Add a ment  | 

2 Answers 2

Reset to default 4

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);
});

It's because this is in a function that is nested within another function and the nested function doesn't have the same invocation context as the outer one. The first one works because you are caching the object that the outermost this is referencing and you are then able to correctly reference it in the inner function.

You can read more about the volatility of this here.

发布评论

评论列表(0)

  1. 暂无评论