0

Possible Duplicate:
Pass correct “this” context to setTimeout callback?

I have a problem with my little script.

function test() {
    this.arr = new Array('a','b','c');
    this.func = function() {
        //Do something with this.arr. But it's undefined.. WHY???
    }
    this.Start = function() {
        this.Interval = setInterval(this.func, 1000);
    }
}

var Test = new test();
Test.Start();

When I try to do anything with array in "func", it keeps telling me, that the array is undefined. Why?

Community
  • 1
  • 1
techbech
  • 3,754
  • 5
  • 20
  • 28
  • why are you creating a bunch of variables? just do everything where it is needed and see if the variables are getting in the way due to `this` – Noah Passalacqua Aug 05 '12 at 19:48
  • 1
    You capitalisation is odd. Usually only constructors are capitalised, and all other variables (including methods) are lowercase. – Bergi Aug 05 '12 at 19:54

2 Answers2

1

You're getting the wrong this reference, try:

function Test() {
  this.arr = new Array('a','b','c');
  this.func = function() {
    console.log(this.arr);
  };
  this.start = function() {
    var fun = this.func.bind(this);
    this.interval = setInterval(fun, 1000);
  };
}

var test = new Test();
test.start();

This article about this is a really interesting if you need more information: Function invocation and this

Also, note that I've changed the case on some symbols. Remember, functions that are meant to be used as constructors start with a uppercase letter, variables and methods use lowercase.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232
  • While I agree with the style tips, I strongly suggest you give a reference, since there is no standards body (or BDFL) for JavaScript style. – kojiro Aug 05 '12 at 19:53
1

Timers/Intervals are called on global scope so 'this' is set to 'window'. To get around this, you can pass a third option to setInterval() which will be used as a parameter for the specified function call.

function Test(){
    this.array = new Array('a','b','c');
    this.function = funct(){ }
    this.start = function(){
        this.Interval = setInterval(function(passedObj){
            passedObj.funct.call(passedObj);
        },1000,this);
    }
}
var testObj = new Test();
testObj.start();

Reading the comments below, you will see this is meant for nodejs. This, however, will not work for IE8 and/or earlier.

SReject
  • 3,774
  • 1
  • 25
  • 41