I have a problem in regard to setInterval
that I can't figure out.
There is the problem with the scope when calling setInterval
or timeout from within an object, but still I can't wrap my head around it.
I tried to put my stuff inside an anonymous function, it won't work.
This is basicly my problem, simplified to the bare bones:
function Scenario(){
var ships = [];
this.ini = function(){
for (var i = 0; i < ships.length; i++){
timeoutID1 = setTimeout(ships[i].ding, 1000);
timeoutID2 = setTimeout(ships[i].bing, 1000);
}
}
this.setShips = function(){
var ship = new Ship("ship");
ships.push(ship);
}
function Ship(name){
this.name = name;
this.ding = function(){
intervalID1 = setInterval(function(){
console.log("ding");
}, 500)
}
this.bing = function(){
var _this = this;
intervalID2 = setInterval(function(){
console.log(_this.name);
}, 500)
}
}
this.setShips();
}
var scenario = new Scenario();
scenario.ini();
http://jsfiddle.net/ancientsion/xkwsn7xd/
Basicly, console.log("ding")
works, console.log(_this.name)
doesn't.
Why?
By the time
setTimeout()
gets around to call your method, it only sees the function and not the invocation context (i.e. the object to bind it to); much like this:Basically, you need to provide
setTimeout()
with a prewired method invocation:The "magic" happens with
.bind()
as it returns a new function that will havethis
set up properly.You put
ships[i].bing
in setTimeout turns out that the caller of bing is not ships[i] but global, so_this
is pointing to global actually.You should define the value
_this
inShip
function:This is your problem simplified to bare bones:
It may help to see another example to understand why the above doesn't work:
In JavaScript
this
depends on how you call your function.ship.ding()
will setthis
to thesheep
object. Bareding()
call will setthis
to thewindow
object.You can bind the function to the object you want by using
.bind()
method. (Function.prototype.bind())ding
is now permanently bound to thesheep
object. You can use exactly the same approach withsetTimeout
:Hoist _this out of the bing function.
you should have
Javascript is imperative so you need to follow the execution path carefully. In function Ship, this points to a Ship object, in function bing, this points to the global scope (window). You need to save a reference to this so that you can refer back to it in these types of functions.