1

I have this Javascript class:

function PageManager () {
    this.timeoutHandler = function () {
        alert ("hello");
    }

    this.startTimeout = function () {
        this.timeout = setTimeout ("this.timeoutHandler()", 1000);
    }
}

When I call obj.startTimeout (); I get this error:

this.timeoutHandler is not a function

How do I call a class function in the timeout?

Nik
  • 7,113
  • 13
  • 51
  • 80

2 Answers2

7

If you pass a string to setTimeout, the code is evaluated in the global scope. Always pass a function reference:

this.startTimeout = function () {
    var self = this;
    this.timeout = setTimeout(function() {
       self.timeoutHandler();
    }, 1000);
}

Or if you don't need a reference to the object inside timeoutHandler, then you can pass the function directly:

this.timeout = setTimeout(this.timeoutHandler, 1000);
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
3

The problem is that you're passing setTimeout a string. This string is eval'd, with a scope of the window. So if you were to do this:

    this.timeout = setTimeout ("console.log(this);", 1000);

... with Firebug installed, you'd see that this is window, which does not have a timeoutHandler method, of course.

This is why you should never, ever pass setTimeout a string. Give it a function reference instead.

function PageManager () {
    this.timeoutHandler = function () {
        alert ("hello");
         console.log(this);
    }

    this.startTimeout = function () {
        this.timeout = setTimeout (this.timeoutHandler, 1000);
    }
}
obj = new PageManager ();
obj.startTimeout();

When you execute this code, you'll have the scope you're expecing.

Chris Baker
  • 49,926
  • 12
  • 96
  • 115