Scope When Doing OO Javascript Callbacks
Solution 1:
Modify init
to bind the callback to the original context:
this.init = function() {
this.connection.detectInitialConnection(
this.initialConnectionDetected.bind(this));
}
Unfortunately, bind
is not supported in all browsers, but you can capture the current value of this
in a closure to achieve a similar effect:
this.init = function() {
var that = this;
this.connection.detectInitialConnection(function(detected) {
that.initialConnectionDetected(detected);
});
}
Yet another approach is to make detectInitialConnection
capable of handling an optional context parameter:
this.detectInitialConnection = function(callbackFunction, _this){
setTimeout(function() {
callbackFunction.apply(_this || this, arguments);
}, 1000, [true]);
}
You'd then call it like this:
this.init = function() {
this.connection.detectInitialConnection(
this.initialConnectionDetected, this);
}
The point in each of these examples is to retain a reference to the value of this
from the context in which detectInitialConnection
was called.
Solution 2:
setTimeout will run the passed function bound to window
. You can override this with ES5's bind
:
this.connection.detectInitialConnection( this.initialConnectionDetected.bind(this) );
This doesn't work in older browsers, but the provided MDN link has a workaround.
Solution 3:
this is tricky in javascript especially as it relates to constructors and passing functions around. If you do this it will work:
//AppController Class
var AppContoller = function(){
this.body = $("body");
var self = this;
this.init = function(){
this.connection = new ConnectionMonitor();
this.connection.detectInitialConnection( this.initialConnectionDetected );
}
//callback function I pass
this.initialConnectionDetected = function(bool){
if(bool){
trace("app connected? "+bool); // logs - "app connected? true"
self.showOnlineSwf();
}
else{
}
}
this.showOnlineSwf = function(){
trace("i'm online");
}
}
Solution 4:
The other answers are correct, but nobody seems to mention that Function.prototype.bind
is not supported in all browsers. To make it work, you'll want to include Kris Kowal's es5-shim library.
Solution 5:
this.initialConnectionDetected
will pass the function, but without the information that it should be executed on the instance.
Calling this.foo()
will pass this information, but only when called directly, not when passed around and called later (which is what you're doing).
You have to bind this information (i.e. the this
value, which is the instance) using e.g. .bind
:
this.connection.detectInitialConnection(this.initialConnectionDetected.bind(this));
Note that .bind
is not available in older browsers, but there are shims available which mimic the behaviour of it.
Post a Comment for "Scope When Doing OO Javascript Callbacks"