0

I tried searching for this for about an hour and can't seem to find a solution that works for me. I have a function (Function2) inside an object that is called by an interval. Function2 cannot find Function1, and is saying the method does not exist. Why might this be, or what is wrong with my syntax?

var ClassA = function ()
{
    this.attribute = "";

    this.function1 = function()
    {
        alert("Function 1");
    };

    this.function2 = function()
    {
        alert("Function 2");
        this.function1(); <----- Does not exist?
    };

    this.function3 = function()
    {
        setInterval(this.function2, 5000);
    };
};

var CLASS_A = new ClassA();
CLASS_A.function3();
Taztingo
  • 1,915
  • 2
  • 27
  • 42
  • 1
    `this` is late-bound in JS. Capture its value to use inside the functions. – Dave Newton Feb 03 '15 at 17:55
  • 1
    In other words: put `var that = this;` in top of ClassA and replace all the `this` with `that`. – Jonathan Feb 03 '15 at 17:57
  • It's a known JS pattern... use `var self = this;` at the top of your class, and then refer to inner functions using `self.functionName` Once you're inside function2, 'this' refers to the function2 scope, not the class scope. – Jason Maggard Feb 03 '15 at 17:58
  • This question has been asked and answered a dozen times here on SO. See http://stackoverflow.com/questions/27570546/setinterval-this-again, http://stackoverflow.com/questions/14829962/yet-another-setinterval-this-not-working, http://stackoverflow.com/questions/2749244/javascript-setinterval-and-this-solution/2749272#2749272, etc. –  Feb 03 '15 at 18:06

2 Answers2

0

You have to look carefully about what this means in JavaScript and in what context your function is being called. You can ensure that the context is what you intend by using the bind method of Function, as in the following edit:

var ClassA = function ()
{
    this.attribute = "";

    this.function1 = function()
    {
        alert("Function 1");
    };

    this.function2 = function()
    {
        alert("Function 2");
        this.function1(); // Exists but only on the ClassA, not on Window
    };

    this.function3 = function()
    {
        setInterval(this.function2.bind(this), 5000);
    };
};

var CLASS_A = new ClassA();
CLASS_A.function3();
MatthewG
  • 8,583
  • 2
  • 25
  • 27
0

The setInterval behaves asynchronously. When you provide this.function2 as parameter to setInterval, you're basically providing a callback method. When setInterval has reached 5000 it calls your callback method.

The "this" keyword changes depending on the context. The callback context is very different from your object's "ClassA" context. It's not the same "this".

The trick is to do this:

var ClassA = function(){

   var that = this;

   //And then everywhere else use that instead of this.
   that.function1 = function() { ... 

   that.function2 = function() { ...
        that.function1

   that.function3 = function ....

}

Good luck.

TchiYuan
  • 4,258
  • 5
  • 28
  • 35