3

A simplified example:

// Let's create a new object
function MyObject() {
    //
}

// Add some method to this object
MyObject.prototype.myFunctionA = function() {
    //
}

// Another method
MyObject.prototype.myFunctionB = function(arg) {
    // AJAX GET request          
    $.get('script.php', { par : arg }, function(data) {

        // and here in the callback function    
        // I need to call MyObject.prototype.myFunctionA method!
        // but "this" references callback function so
        // I don't know how to access MyObject here

    });
}

I have explained my issue in the comments. How can I do that?

3 Answers 3

7

simplest:

// Let's create a new object
function MyObject() {
    //
}

// Add some method to this object
MyObject.prototype.myFunctionA = function() {
    //
}

// Another method
MyObject.prototype.myFunctionB = function(arg) {
    // AJAX GET request       
    var me = this;   
    $.get('script.php', { par : arg }, function(data) {
        // use me.something instead of this.something
    });
}

reusable (using scope trapping):

function createDelegate(obj, handler)
{
    return function() {
        handler.apply(obj, arguments);
    }
}

then

MyObject.prototype.myFunctionB = function(arg) {
    // AJAX GET request       
    var me = this;   
    $.get(
        'script.php', 
        { par : arg },
        createDelegate(this, function(data) {
        // use this.something
        })
    );
}

So, some code in relation to the comments below, createDelegate can also be used in a few different ways, one of which being:

function createDelegate(obj, handler)
{
    handler = handler || this;
    return function() {
        handler.apply(obj, arguments);
    }
}

Function.prototype.createDelegate = createDelegate;

this allows you to do things like:

var someObj = {a:1, b:function() {return this.a;}};
var scopedDelegateForCallback = someObj.b.createDelegate(whateverobj)

you can do tricks to get parent too, but that's too much for me to bother with atm.

or, you can do something like this:

function createDelegate(handler, obj)
{
    obj = obj || this;
    return function() {
        handler.apply(obj, arguments);
    }
}

Object.prototype.createDelegate = createDelegate;

and to use it:

someObj.createDelegate(someObj.b);

or maybe:

function createDelegateForMember(handlerName, obj)
{
    obj = obj || this;
    return function() {
        obj[handlerName].apply(obj, arguments);
    }
}

Object.prototype.createDelegate = createDelegateForMember;

then

someobj.createDelegate("b");
Sign up to request clarification or add additional context in comments.

5 Comments

I like your createDelegate function, but I think it'd be even better if you moved the obj parameter to the end of the parameter list and made it optional, defaulting to this. That would save some code in the most common use-case.
if you're not specifying 'this', it's useless to use the createDelegate function :)
No, I meant something like this: function createDelegate(handler, obj) { return function () { handler.apply(obj || this, arguments); }; }. And calling it like this: $.get('script.php', { par: arg }, createDelegate(function (data) { /* do something */ }));.
yeah, but 'this' in 'obj || this' refers to the 'this' of the function returned by createDelegate, which will be set to 'window' (as, for that matter, will the 'this' for createDelegate) - TBC for readability
i was going to post another comment, but will put it in my post, give me a minute :)
6

you can assign "var self = this" in MyObject.prototype.myFunctionB before calling the $.get then you can use the alias "self" inside the callback.

MyObject.prototype.myFunctionB = function(arg) {
    var self = this;

    $.get('script.php', { par : arg }, function(data) {
       alert(self);
    });
}

1 Comment

Clean and simple. Great answer!
4

JavaScript functions "close over" variables in outer scopes, so you can do this:

// Another method
MyObject.prototype.myFunctionB = function(arg) {
    // Save `this` reference for use in callback.
    var that = this;

    // AJAX GET request
    $.get('script.php', { par : arg }, function(data) {

        // Now `that` holds the contents of the current `MyObject`.
        // So you can call other methods.
        that.myFunctionA();
        // ... etc ...

    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.