8

I have an object with a method that I’d like to pass to a function as a callback. However, inside the callback, this no longer refers to my object. Why not?

I’m familiar with using a variable to get around the problem when passing a function literal:

var obj = {
    a: function () {
        var me = this;

        console.log(this);

        setTimeout(function () {
            console.log(this); // Not obj
            console.log(me);   // This works!
        }, 100);
    }
};

How can I fix it in this case?

var obj = {
    b: function () {
        setTimeout(this.callback, 100);
    },
    callback: function () {
        console.log(this); // =(
    }
};
Ry-
  • 218,210
  • 55
  • 464
  • 476
missingcat92
  • 787
  • 2
  • 10
  • 21

1 Answers1

11

Yes, this can be kind of tricky in Javascript. The problem is that its value depends on how you call the function.

obj.callback(); //ok

var f = obj.callback;
f(); //does not look like a method call
     //Javascript does not pass the this!

The usual workaround is passing a wrapper callback like you did in b), except that the common name for the me variable is that (you sometimes see self too)

var that = this;
setTimeout( function(){ return that.callback(); }, 300);

The other alternative is to use the bind method from functions

setTimeout( this.callback.bind(this) , 300)

Note that bind is not supported in IE 8 (you might need a shim in that case).


For more:

Maintaining the reference to "this" in Javascript when using callbacks and closures

Community
  • 1
  • 1
hugomg
  • 68,213
  • 24
  • 160
  • 246
  • 1
    note that Function.prototype.bind is part of ECMAScript5, it will not work on IE6/7/8 and Firefox 3.6 (and less relevant as it auto-updates, older Chromes like < 6) – gonchuki Nov 19 '11 at 03:08
  • It is easier to understand `this` when you think of variables/properties as pointers to functions instead of being functions themselves. `obj.callback` is just a pointer to a function that has no idea who points to it and can infact have any number of pointers to it. So because of this, `this` for the function can only be resolved during call time and has a few simple rules for it. So always remember it's resolved during call-time and life will be easier :) – Esailija Nov 19 '11 at 06:00
  • this.callback.bind(this) is what I was looking for. – Basil Musa Jun 13 '17 at 12:42