Javascript 为什么removeeventlistener在此对象上下文中不起作用?

Javascript 为什么removeeventlistener在此对象上下文中不起作用?,javascript,dom-events,Javascript,Dom Events,我正在开发一个游戏,我想抽象我的UI,并根据不同的游戏状态绑定解除绑定的事件。但是我不明白为什么这个事件没有被删除。处理程序中的作用域似乎是正确的 相关(精简)js: 然而,如果我以这种方式删除事件,它就会起作用: (...) bind : function(el, cb) { this.el = el; this.cb = cb; var self = this; this.el.addEventListener('click', function() {

我正在开发一个游戏,我想抽象我的UI,并根据不同的游戏状态绑定解除绑定的事件。但是我不明白为什么这个事件没有被删除。处理程序中的作用域似乎是正确的

相关(精简)js:

然而,如果我以这种方式删除事件,它就会起作用:

(...)

bind : function(el, cb) {
    this.el = el;
    this.cb = cb;
    var self = this;
    this.el.addEventListener('click', function() {
        self.cb();
        self.el.removeEventListener('click', arguments.callee, true);
    }, true);
}

(...)

.bind
返回一个新的函数<代码>this.handler.bind(this)!=这个.handler!您必须以某种方式存储对新函数的引用

例如,将引用存储在变量中并使用闭包:

var handler = this.handler.bind(this);
this.el.addEventListener('click', handler, true);

this.unbind = function() {
    this.el.removeEventListener('click', handler, true);
}
除了
参数.callee
,您还可以为函数指定一个名称:

this.el.addEventListener('click', function handler() {
    self.cb();
    self.el.removeEventListener('click', handler, true);
}, true);

我建议使用以下方法,而不是使用同样需要更多内存的绑定:

您可以将具有
handleEvent
属性的对象
obj
用作任何DOM对象上的处理程序,以捕获其事件,并将事件处理程序的上下文设置为该对象
obj
,而无需使用
Function.prototype.bind

这样,您还可以删除处理程序,因此

songNode.removeEventListener("click", song);

酷!谢谢你的快速回复。我不知道.bind正在创建新函数。:)为什么不?->this.el.addEventListener('click',this.handler.bind(this),true);和this.el.removeEventListener('click',this.handler.bind(this),true)@阿尔贝托卡尼亚:我在回答中已经解释了这一点
.bind
总是返回一个新的(即不同的)函数。+1很好的建议,尽管我不认为一个或两个以上的函数对内存占用有任何重大影响。谢谢。这取决于有多少对象最终将使用绑定版本的函数,但是的,这里的主要优势不是内存:-)
var song = {
    handleEvent: function (event) {
      switch (event.type) {
        case: "click":
          console.log(this.name);
          break;
      }
    },
    name: "Yesterday"
};

songNode.addEventListener("click", song);
songNode.click(); // prints "Yesterday" into console
songNode.removeEventListener("click", song);