2011-11-22 56 views
0
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); 
    } 
}; 

但在onclickthis被绑定到map。我希望它可以绑定到Foo的实例。
请注意,我不能使用匿名函数作为addEvent的第二个参数,因为我需要稍后移除侦听器。句柄 '这个' 事件监听器

回答

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/(忽略警告的内容,重要的是,它得到了那里!)

+0

在'start'中仍然是'this'仍然引用'Foo'的实例吗? – wong2

+0

@ wong2是的,它似乎是 - http://jsfiddle.net/infernalbadger/Ypgh5/1/单击正确工作在两个div –

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

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

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

这个答案是类似于理查德·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); 
};