I have just answerd for something similar here :
How can I pass a parameter to a setTimeout() callback?
The setTimeout function fix the context to the window, so it's not possible to do what you want !
To do it i have wrapped the setTimeout function in another one which can set the context :
myNass_setTimeOut = function (fn , _time , params , ctxt ){
return setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
var _deepResultFunction = function _deepResultFunction(){
//_deepFunction(_deepData);
_deepFunction.apply( _deepCtxt , _deepData);
};
return _deepResultFunction;
})(fn , params , ctxt)
, _time)
};
// lets try this functions :
for(var i=0; i<10; i++){
setTimeout(function(){console.log(i)} ,1000 ); // stock setTiemout in closure
}
for(var i=0; i<10; i++){
setTimeout( console.log(i) ,1000 ); // stock setTiemout direct call
}
for(var i=0; i<10; i++){
setTimeout(console.log ,1000 , i); // stock setTiemout not compatible IE
}
for(var i=0; i<10; i++){
myNass_setTimeOut(console.log ,1000 , [i] , console); // wrapped setTimeout
}
So to answer your question :
var person = {
first: 'joe',
last: 'doe',
getName: function(){
console.log(this.first + ' ' + this.last);
}
}
setTimeout(person.getName(), 2000);
When you launch : setTimeout(person.getName(), 2000);
setTimeout will execute in the future 2s (2000ms) the 1st argument !
But what is the value of your 1st argument ? : the result of your function person.getName( )
,
so it's equivalent of :
var _arg1 = person.getName();
setTimeout(_arg1 , 2000);
which is very different of :
var _arg1 = person.getName;
setTimeout(_arg1 , 2000);
The first case you pass the result of a function to setTimeout which wait a reference to a function.
In the second case you pass a reference to a function (good it's what expected), but not in the good context !
So, now you have to fix the context :
whith the core javascript function :apply
Now try this :
var _arg1 = function(){ person.getName.apply(person) };
setTimeout(_arg1 , 2000);
myNass_setTimeOut(person.getName , 2000 , null , person);
So you have two choice :
- Fixing the context for every argument you pass to setTimeout.
- Use a function which do it for you
the myNass_setTimeOut function will make the trick !
Now, let see something a little bit more deeper :
var person = {
first: 'joe',
last: 'doe',
getName: function(){
console.log(this.first + ' ' + this.last);
} ,
say : function(sentence){
console.log(this.first + ' ' + this.last + ' say : ' + sentence)
}
}
How could pass argument sentence to a setTimeout ?
var heSay = "hello !"; setTimeout(person.say(heSay) , 1000 ); heSay = "goodBye !";
// not good : execute immediatly
var heSay = "hello !";setTimeout(function(){person.say(heSay)} , 1000 ); heSay = "goodBye !";
// not good : hesay googbye
var heSay = "hello !"; setTimeout(person.say , 1000 , heSay); heSay = "goodBye !";
// not good bad context
var heSay = "hello !"; setTimeout(function(whatHeSay){person.say(whatHeSay)} , 1000 , heSay);heSay = "goodBye !";
// GOOD ! ok but not compatible with IE
var heSay = "hello !"; myNass_setTimeOut(person.say , 1000 , [heSay] , person ); heSay = "goodBye !";
// just good !
hope this help you !
edit :
for modern browser suporting bind don't take care about that do what say
here @dandavis