Reputation: 339
Let's consider this piece of JavaScript:
function Person(name) {
this.name = name;
}
Person.prototype.showName = function() {
alert(this.name);
}
var mike = new Person("mike");
//mike.showName();
window.name = "window";
I don't understand the difference between the behavior of
setTimeout(mike.showName(), 5000);
and
setTimeout(function(){
mike.showName();
}, 5000);
Why is the behavior different? It really confuses me. Thanks.
Upvotes: 21
Views: 104415
Reputation: 19719
If the accepted answer is just too long to read:
setTimeout(mike.showName(), 5000);
This will execute whatever mike.showName()
returns after 5,000 milliseconds.
setTimeout(function(){ mike.showName(); }, 5000);
This will execute anonymous function after 5000 milliseconds that calls mike.showName()
, the actual function.
Another way to achieve same effect:
setTimeout(mike.showName.bind(mike), 5000);
Upvotes: 28
Reputation: 60414
Your question really has nothing at all to do with setTimeout
. You simply need to understand the difference between a function call and a reference to a function.
Consider these four assignments:
var one = function() { mike.showName(); };
var two = mike.showName;
var three = mike.showName();
var four = (function() { mike.showName(); })();
The first two assign a reference to a function to their respective variables. The last two, however, call functions (that's what the parens are for) and assign their return values to the vars on the left-hand side.
How this relates to setTimeout:
The setTimeout
function expects as its first argument a reference to a function, so either one
or two
above would be correct, but three
and four
would not. However, it is important to note that it is not, strictly speaking, a mistake to pass the return value of a function to setTimeout
, although you'll frequently see that said.
This is perfectly fine, for example:
function makeTimeoutFunc(param) {
return function() {
// does something with param
}
}
setTimeout(makeTimeoutFunc(), 5000);
It has nothing to do with how setTimeout
receives a function as its argument, but that it does.
Upvotes: 68
Reputation: 10941
setTimeout(mike.showName(), 5000);
executes mike.showName()
immediately and passes the return value to setTimeout()
setTimeout(function(){ mike.showName(); }, 5000);
passes a pointer to the function instead. That way setTimeout
can execute the function, rather than it's return value.
Upvotes: 6
Reputation: 318508
It's not a performance issue. One of the ways you showed simply doesn't work (it calls the function immediately instead of when the timeout fires).
setTimeout(mike.showName(), 5000);
will execute the showName
function and sets its return value as the timeout callback which won't work.
setTimeout(function(){ mike.showName(); }, 5000);
creates an anonymous function and sets this as the timeout callback. When the timeout fires, the function is called and calls your showName()
function.
Fyi, setTimeout('mike.showName();', 5000);
would also work. But don't do that - it's just as bad as using eval()
. Besides that it makes your code less readable since the code in the string cannot be syntax-highlighted.
Upvotes: 10