tags:

views:

99

answers:

4

I have a JavaScript class that looks like this:

function SomeFunction()
{
    this.doSomething(function()
    {
        this.doSomethingElse();
    });

    this.doSomethingElse = function()
    {

    }
}

This code throws an error because the scope of "this" inside the function that is passed into doSomething() is different that than the scope of "this" outside of that function.

I understand why this is, but what's the best way to deal with this? This is what I end up doing:

function SomeFunction()
{
    var thisObject = this;

    this.doSomething(function()
    {
        thisObject.doSomethingElse();
    });

    this.doSomethingElse = function()
    {

    }
}

That works fine, but it just feels like a hack. Just wondering if someone has a better way.

+6  A: 

That is the correct and commonly-accepted workaround. It's sort of kludgy but it's what everybody does. Typically this extra variable is named self, as in:

function SomeFunction()
{
    var self = this;

    this.doSomething(function()
    {
        self.doSomethingElse();
    });

    this.doSomethingElse = function()
    {

    }
}
John Kugelman
Be aware that `self` is a property of the window object in browsers that points at itself, though this is unlikely to cause any problems.
Tim Down
+2  A: 

this has dynamic "scope". That means that it is set up by whatever binds it, and this is bound by a "method call". That is, any time in your program you see this: w.f() then while f is executed, this is dynamically bound to f, even if f had this in its lexical scope.

Most JavaScript frameworks provide some facilities for dealing with this exact problem. With Prototype.js (for example) you can do this:

this.doSomething(function() { this.doSomethingElse(); }.bind(this));

Your "hack" however is fine. I usually do a (function (self) { ... })(this) around any functions that I need a lexically-scoped this-like variable.

geocar
A: 

This commenter had what I was looking for (although the other answers are good too):

@Jon Kruger See this, check out their article for call, too: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Apply– Jonathon 44 mins ago

Jon Kruger
A: 

It's also worth mentioning that the next version of ECMAScript (the language spec for JavaScript) is going to introduce Function.bind(), which will let you specify a permanent context for a function.

DDaviesBrackett