November 11, 2011

SetInterval With Context

When i started experimenting with the "OOP" structures that one could use in Javascript, there was something that always annoyed me; the timeOuts and setIntervals think that the context is the global object (window) instead of the current object; so the 'this' keyword points to the global object.

function hero(){
 this.speed = 0
 this.getFaster = function(){
  this.control = setTimeout(function(){
   console.log(++this.speed) // returns NaN
  },1000) 
 }
}

var superman = new hero();
superman.getFaster()

Yeah, yeah... i have read all about why it does that... the thing is... i don't care why it does that! I just want it to work!

The good news is that it haves multiple work-arounds but the one i find the best is this simple function:

setIntervalWithContext = function(code,delay,context){
 return setInterval(function(){
  code.call(context)
 },delay) 
}

setTimeoutWithContext = function(code,delay,context){
 return setTimeout(function(){
  code.call(context)
 },delay) 
}

Now i can call this new function and have an in-context setInterval, awesomeness!

function hero(){
 this.speed = 0
 this.getFaster = function(){
  this.interval = setIntervalWithContext(function(){
   console.log(this.speed++)
   // Run Forest! RUN!!!
  },100,this)
 }
}

var flash = new hero();
flash.getFaster()

And because the function returns the ID of the interval, you can save it in a variable and clear the interval anywhere you want (including inside the callback itself)

this.interval = setIntervalWithContext(function(){
 if(this.speed++ > 100){
  clearInterval(this.interval)
 }
},100,this) 


In other news:
The graphic tool for my little project "CreativeTextBoxes" is now available:
More info at: http://creativetextboxes.com/
Graphic tool at: http://creativetextboxes.com/graphic_tool.php

3 comments:

You can use [CODE][/CODE] to post Javascript code.
You can start a sentence with ">" to make a quotation.