Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object method loses its scope when called using setInterval

Tags:

javascript

Is there any way to print out the value of the array players like in the example below? I've tried to find a solution for hours now...

function Room(name, id, owner) {
    this.players = [];
    this.movementz =  function() {
        console.log(this.players);
    }
}

I'm calling the function using setInterval, like this:

setInterval(room.movementz, 1000);
like image 688
user3534757 Avatar asked Dec 23 '14 22:12

user3534757


People also ask

Does setInterval affect performance?

This is unlikely to make much of a difference though, and as has been mentioned, using setInterval with long intervals (a second is big, 4ms is small) is unlikely to have any major effects.

Is it good to use setInterval in Javascript?

In order to understand why setInterval is evil we need to keep in mind a fact that javascript is essentially single threaded, meaning it will not perform more than one operation at a time.

What can I use instead of setInterval?

Nested setTimeout calls are a more flexible alternative to setInterval , allowing us to set the time between executions more precisely. Zero delay scheduling with setTimeout(func, 0) (the same as setTimeout(func) ) is used to schedule the call “as soon as possible, but after the current script is complete”.

Does setInterval repeat?

Yes, setInterval repeats until you call clearInterval with the interval to stop. By way of example, the following code will count to 5. setInterval sets up the counter, setTimeout sets up a single event in 5 seconds to stop the counter, and clearInterval stop counting.


1 Answers

The problem here is about the this object: creating your object and manually calling it's movementz method will work because the this element is the object itself, but using setInterval will cause the method to be called with this === window.

Here is an example:

var room = new Room();

room.movementz(); // []
setInterval(room.movementz, 1000); // undefined

This happens because when the movementz method gets called by setInterval, the this object is window, so, to fix this, you'll have to force the function to be called using room as this. You can easily accomplish this using the bind method, here's an example:

var room = new Room(),
    players = "hello";

setInterval(room.movementz, 1000);
// this will output "hello" because this === window

setInterval(room.movementz.bind(room), 1000);
// this will output [], because now this === room
like image 128
Marco Bonelli Avatar answered Oct 19 '22 04:10

Marco Bonelli