1

In one of my classes, a method performs AJAX requests. In the callback function of a request, I need to call another method of my object, using this. But this does not refer to my object in this context, so I don't know how to do... Is it only possible ?

To clarify, please consider the following code :

function MyClass(arg) { 
    this.foo = arg; 
} 

MyClass.prototype = { 
    myMethod: function() { 
        console.log("I am myMethod");
    },
    myGet: function (){
        $.get("http://example.iana.org/",function(data){
            this.myMethod(); // does not work, because 'this' does not refer to my object
        });
    }
} 

var obj = new MyClass("Javascript is complicated"); 

obj.myGet();
little-dude
  • 1,544
  • 2
  • 17
  • 33

1 Answers1

7

You can define a variable to store this in the closure :

myGet: function (){
    var _this = this;
    $.get("http://example.iana.org/",function(data){
        _this.myMethod();
    });
}

or use $.proxy :

myGet: function (){
    $.get("http://example.iana.org/", $.proxy(function(data){
        this.myMethod();
    }, this));
}

or, if you don't do more than calling myMethod in the callback :

myGet: function (){
    $.get("http://example.iana.org/", $.proxy(this.myMethod, this));
}

In modern browsers you can also use bind. When I don't have to be compatible with IE8 I do

myGet: function (){
    $.get("http://example.iana.org/", this.myMethod.bind(this));
}
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • +1 `$.proxy` is cooler – techfoobar Jun 10 '13 at 09:03
  • You could also bind a private member to `that` upon construction of the object. – Henrik Andersson Jun 10 '13 at 09:04
  • Thank you ! I'll accept your answer in 11 minutes ;) Is there a good reason to use `$.proxy()` instead of defining a second variable ? – little-dude Jun 10 '13 at 09:05
  • 2
    @emmasculateur Personally I have no problem with the additional variable, especially when you give it a less generic name, but `$.proxy` might make the intent clearer. – Denys Séguret Jun 10 '13 at 09:06
  • 1
    Sometimes using the additional variable is not possible. For instance if you're many levels deep into callbacks when writing asynchronous code, you can lose your reference to the original `this`. In such an instance `$.proxy` can come to the rescue. – Matt Harrison Jun 10 '13 at 09:13
  • 2
    @MattHarrison Not quite sure on that - it should work fine as long as you create a closure to store the current `this` reference, seeing as that is basically what `$.proxy` does internally. – Fabrício Matté Jun 11 '13 at 06:43
  • @FabrícioMatté I could very well be wrong. If you run this code https://gist.github.com/mtharrison/549e78f3ba36d2cd60cf you can see what I'm getting at, I'd use `$.proxy` or `bind` here when passing the callback as an argument. Is there a better way? – Matt Harrison Jun 11 '13 at 08:25
  • 1
    @MattHarrison "better" is relative - `bind` and `$.proxy` are the shorter and most syntactically sweet syntax. I just meant that where these are used, you may also wrap yet another function around it storing the `this` reference that you can then use to `call`/`apply` the inner function. – Fabrício Matté Jun 11 '13 at 08:33