views:

1077

answers:

4

Within my a certain function of a class, I need to use setInterval to break up the execution of the code. However, within the setInterval function, "this" no longer refers to the class "myObject." How can I access the variable "name" from within the setInterval function?

function myObject() {
    this.name = "the name";
}

myObject.prototype.getName = function() {
    return this.name;
}

myObject.prototype.test = function() {
    // this works
    alert(this.name);

    var intervalId = setInterval(function() {
     // this does not work
     alert(this.name);

     clearInterval(intervalId);
    },0);
}
+9  A: 
myObject.prototype.test = function() {
    // this works
    alert(this.name);
    var oThis = this;
    var intervalId = setInterval(function() {
        // this does not work
        alert(oThis.name);

        clearInterval(intervalId);
    },0);
}

This should work. The anonymous function's "this" is not the same "this" as your myObject's "this."

jacobangel
I tend toward 'self' but that's me
sblundy
I actually prefer to use "superThis" but it didn't seem appropriate for an example :)
jacobangel
"self" is a reserved keyword in javascript, you should'nt use it.
Luca Matteis
"self" is not a reserved word. It's just a special variable.
Crescent Fresh
I also use self, its a very recognisable idiom. It is true that browsers also place a self property on the window object, I can't think why, if I want to access the window I use window.
AnthonyWJones
A: 

This is what binding is for in Prototype:

function myObject() {
    this.name = "the name";
}

myObject.prototype.getName = function() {
    return this.name;
}

myObject.prototype.test = function() {
    // this works
    alert(this.name);

    var intervalId = setInterval(function() {
        // this does not work
        alert(this.name);

        clearInterval(intervalId);
    }.bind(this),0);
}
Bit Destroyer
I'm not using the Prototype framework, but this would work otherwise.
Chris B
My apologies! Seeing the prototype keyword throws me off sometimes.
Bit Destroyer
+1  A: 

Here's the prototype bind function

Function.prototype.bind = function( obj ) {
    var _this = this;
    return function() {
        return _this.apply( obj, arguments );
    }
}
meouw
This implementation of Function.bind() does not support partial function application as proposed for ECMAScript Harmony, so may cause compatibility problems further down the line. You can still use it of course, just best call it something else if you want to bang it into the Function prototype.
bobince
Thanks bobince, I wasn't aware of that.
meouw
A: 

Please note that s13james's answer is incomplete in that bind() is not a standard feature and must be provided elsewhere - one way is using the prototype.js Javascript framework, while another will be to do it yourself using meouw's code example.

If you don't use bind() (which is nifty, I must say) then djangel's response is what you could have done, and is what I most often do.

Guss