2011-11-22 77 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); 
};