8

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
  • 2
    @Jon Kruger That's what I do, too. I think that's pretty normal. You can change this with call and apply, but that doesn't always fit what you're doing well. Another option is passing this as a parameter, but that feels like even more of a hack. Commented Feb 12, 2010 at 18:03
  • @Jonathon What do you mean by "You can change this with call and apply"? Commented Feb 12, 2010 at 18:16
  • 1
    @Jon Kruger See this, check out their article for call, too: developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/… Commented Feb 12, 2010 at 18:20
  • 1
    JavaScript: The Good Parts by Douglas Crockford is a good reference that goes over this very question. Commented Feb 12, 2010 at 18:23
  • 1
    also remember that if you call SomeFunction without the new operator (eg. SomeFunction(); ) this refers to window. Commented Feb 12, 2010 at 22:33

4 Answers 4

11

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()
    {

    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

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.
Other names i've seen used quite a bit are that and me, depending on context.
3

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.

Comments

1

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.

Comments

-1

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

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.