1

Consider the following code:

MyClass.prototype.my_func = function () {
    this.x = 10;
    $.ajax({
        // ...
        success: function (data) {
            alert(this.x);
        }
    });
}

It doesn't work, since apparently this is not bound into the closure's execution context. I've been able to work it around by introducing another variable:

var _this = this;

And this works inside the anonymous function. But looks quite ugly to me. Is there some nice way to handle this?

Andrey Balaguta
  • 1,308
  • 2
  • 21
  • 28
  • 9
    I think your proposed solution -- `var _this = this;` -- is the standard workaround. – LukeH Nov 14 '11 at 14:06
  • The standard workaround uses `var that` instead :P – hugomg Nov 14 '11 at 14:21
  • @LukeH I would go as far as to **not** even call it a *workaround* – ZenMaster Nov 14 '11 at 14:22
  • possible duplicate of [Maintaining the reference to "this" in Javascript when using callbacks and closures](http://stackoverflow.com/questions/7874723/maintaining-the-reference-to-this-in-javascript-when-using-callbacks-and-closu) – hugomg Nov 14 '11 at 14:23

4 Answers4

2

This may look like the ugly solution for you and there are some walkarounds (such as using bind() method to change the context), but this is the best solution I know of.

Alternatively you can change it to:

var self = this;

or give it more meaningful name, but it would be better (in this case) not to change the context, as you may need it some day.

Tadeck
  • 132,510
  • 28
  • 152
  • 198
1

You can make usage of Function.prototype.bind for that:

MyClass.prototype.my_func = function () {
    this.x = 10;
    $.ajax({
        // ...
        success: function (data) {
            alert(this.x);
        }.bind(this);
    });
}

Now the parent context variable is also bound to the anonymous function.

jAndy
  • 231,737
  • 57
  • 305
  • 359
  • @Andy: well, that is very possible. `.bind()` is rather new'ish from the ES5 specs, so it might not be supported by old'ish browsers. – jAndy Nov 14 '11 at 14:28
  • @Andy: In my answer I gave a link to the MDN article about `bind()` and on how to implement it on older browsers, so you can see it there. But I still think it is not the way to go, as I mentioned in my answer. – Tadeck Nov 14 '11 at 14:28
0

the this syntax usually refers to the object, not a function. In your case, this refers to MyClass.

If you're using the variable in the object, you probably forgot to define x in MyClass.

If you're using the variable within the function ONLY I'd define my variables using the var syntax. Variables defined within a function are destroyed when a function ends.

MyClass.prototype.my_func = function () {
    var x = 10;

    $.ajax({
        // ...
        success: function (data) {
            alert(x);
        }
    });
}
Tim S.
  • 13,597
  • 7
  • 46
  • 72
0

The closure will have access to all objects defined in its parent's context. So if we have:

function() {
  var x = 10;
}

Then this is valid:

function() {
  var x = 10;

  (function() {
    alert(2*x); // 20
  }())
}

Therefore, when you define var _this = this you have merely defined a new variable in the parent's context that is available within the closure. See question #4371333 for more information on this "pattern."

Community
  • 1
  • 1
James Sumners
  • 14,485
  • 10
  • 59
  • 77