I am having some trouble getting a callback function to work. Here is my code:
SomeObject.prototype.refreshData = function()
{
var read_obj = new SomeAjaxCall
Your problem here is not exactly a closure or scoping problem. The problem is that when you assign this.readSuccess
to a variable, you assign the function itself without any notion of the object it originaly belongs to.
In the same way, you can take a regular, "stand-alone" function and use it as method of an object:
function hello() {
alert("Hello "+this.planet);
}
var planet = "Earth";
hello(); // -> 'Hello Earth'
var Venus = {
planet: "Venus"
};
hello.apply(Venus); // -> 'Hello Venus'
Venus.hello = hello;
Venus.hello(); // -> 'Hello Venus'
And your problem can be replicated in this example
var helloVenus = Venus.hello;
helloVenus(); // -> 'Hello Earth'
So your problem is to assign this.readSuccess to some variable and having it called as a method of this. Which can be done with a closure as demonstrated by Pointy. Since I don't know what "SomeAjaxCall" actually does, it's hard to know if the value of this
is actually lost and if var obj = this
is actually needed. Chances are that it's not, so you can be fine with this kind of code:
var helloVenus = function() { Venus.hello() }
helloVenus(); // -> 'Hello Venus'
In your case, that would be (edit: adding the arguments passed to the handler) :
SomeObject.prototype.refreshData = function()
{
var read_obj = new SomeAjaxCall(
"read_some_data",
{ },
function () { this.readSuccess.apply(this, arguments) },
function () { this.readFail.apply(this, arguments) }
);
}
As noted previously, several js frameworks offer a bind
function to simplify this kind of issue. But you don't need a complete framework just for this : here is a perfectly fine Function#bind
method that works an plain javascript:
Function.prototype.bind = function(obj) {
var __method = this;
var args = [];
for(var i=1; i
With the help of Function#bind
, you can write:
SomeObject.prototype.refreshData = function()
{
var read_obj = new SomeAjaxCall(
"read_some_data",
{ },
this.readSuccess.bind(this),
this.readFail.bind(this)
);
}