在事件监听器中处理'this'

时间:2011-11-22 08:43:15

标签: javascript javascript-events

function Foo(map){
    this.map = map;
}  
Foo.prototype = {
    onclick: function(e){
        this.bar(e.point);
    },  
    bar: function(point){
        // do something with point
    },  
    start: function(){
        this.map.addEvent("click", this.onclick);
    },
    stop: function(){
        this.map.removeEvent("click", this.onclick);
    }
};  

但在onclick中,thismap绑定。我希望它绑定到Foo的实例 请注意我不能使用匿名函数作为addEvent的第二个参数,因为我需要稍后删除监听器。

4 个答案:

答案 0 :(得分:2)

start()中,创建一个通过本地别名引用外部对象的闭包:

start: function(){
    var self = this;
    this._handlerFunc = function(){ self.onclick.apply(self, arguments); };
    this.map.addEvent("click", this.handlerFunc);
},
stop: function(){
    this.map.removeEvent("click", this._handlerFunc);
}

答案 1 :(得分:1)

这应该给出你想要的结果。通过在匿名函数中创建对象,您可以获得对它的引用。

Foo.prototype = (function() {
    var f = { }
    f.onclick = function(e){
        f.bar(e.point);
    };
    f.bar = function(point){
        // do something with point
    };  
    f.start = function(){
        this.map.addEvent("click", f.onclick);
    };
    f.stop = function(){
        this.map.removeEvent("click", f.onclick);
    };
    return f;
})();  

示例 - http://jsfiddle.net/infernalbadger/Ypgh5/(忽略警报的内容,重要的是它到达那里!)

答案 2 :(得分:0)

您可以更改调用事件处理程序的方式。例如(如果您使用的是jQuery):

$("foo").click((function () {
    var fooObject = new Foo;
    return function (evt) {
        fooObject.onclick.call(fooObject, evt);
    };
}()));

答案 3 :(得分:0)

这个答案类似于Richard D的答案,但由于我们希望原型返回一个新对象,我们可以将它初始化为一个:

Foo.prototype = new function() {
    var self = this;
    this.onclick = function(e){
        this.bar(e.point);
    };
    this.bar = function(point){
        // do something with point
    };  
    this.start: function(){
        this.map.addEvent("click", this.onclick);
    };
    this.stop: function(){
        this.map.removeEvent("click", this.onclick);
    };
    // can use the "self" reference in a callback
    this.someEvent = setTimeout(function(){
        console.log(self);// can't use this here    
    },100);
};