JS复杂的范围按摩

时间:2012-01-06 19:15:34

标签: javascript javascript-events scope

对于我的应用程序中的特定侦听器,我使用以下代码进行范围破坏:

// this is all in a prototype of MyClass
var self = this;
myElement.addEventListener("stuff", function(e){self.doStuff(e)});

这将使doStuff获得所需的this绑定。

当我尝试removeEventListener时出现问题。我想这是因为原生函数签名必须不同?

// in a different prototype of MyClass
var self = this;
myElement.removeEventListener("stuff", function(e){self.doStuff(e)}); // doesn't work

如果我创建一个包含所有范围破坏代码的单独函数,那么该代码中的this绑定将是myElement的不需要的对象。所以问题是:我如何强制监听器范围并仍然能够删除添加的事件监听器?

*请注意,由于项目的性质,禁止以任何方式使用global / static个变量(否则这很简单!)

3 个答案:

答案 0 :(得分:4)

这与范围或存储对this的引用的方式无关。问题是removeEventListener期望引用一个以前被注册为监听器的函数,但是你给它一个以前从未见过的全新函数。

你需要做这样的事情:

var self = this;
var listener = function(e){self.doStuff(e)}
myElement.addEventListener("stuff", listener);
// later
myElement.removeEventListener("stuff", listener);

两个函数的 body 是一样的并不重要;他们仍然是不同的功能。

请参阅:

答案 1 :(得分:1)

无论如何,内联匿名函数是一种非常糟糕的做法,所以我会建议显而易见的:

function MyClass() {
    this.onStuff = this.onStuff.bind(this); //Each instance steals the prototyped function and adds a bound version as their ownProperty
}

MyClass.prototype = {

    onStuff: function (e) { //Prototyped, no instance actually uses this very function
        this.dostuff()
    },

    bind: function () {
        myElement.addEventListener("stuff", this.onStuff);
    },

    unbind: function () {
        myElement.removeEventListener("stuff", this.onStuff);
    }

}

答案 2 :(得分:0)

请参阅removeEventListener on anonymous functions in JavaScript

您无法使用匿名函数删除EventListener。