We all know that passing a string to setTimeout
(or setInterval
) is evil, because it is run in the global scope, has performance issues, is potentially insecure if you're injecting any parameters, etc. So doing this is definitely deprecated:
setTimeout('doSomething(someVar)', 10000);
in favour of this:
setTimeout(function() {
doSomething(someVar);
}, 10000);
My question is: can there ever be a reason to do the former? Is it ever preferable? If it isn't, why is it even allowed?
The only scenario I've thought of is of wanting to use a function or variable that exists in the global scope but has been overridden in the local scope. That sounds to me like poor code design, however...
We all know that passing a string to setTimeout
(or setInterval
) is evil, because it is run in the global scope, has performance issues, is potentially insecure if you're injecting any parameters, etc. So doing this is definitely deprecated:
setTimeout('doSomething(someVar)', 10000);
in favour of this:
setTimeout(function() {
doSomething(someVar);
}, 10000);
My question is: can there ever be a reason to do the former? Is it ever preferable? If it isn't, why is it even allowed?
The only scenario I've thought of is of wanting to use a function or variable that exists in the global scope but has been overridden in the local scope. That sounds to me like poor code design, however...
Share Improve this question asked May 21, 2011 at 11:56 lonesomedaylonesomeday 238k53 gold badges327 silver badges328 bronze badges 3- 1 Based on MDC's documention it seems that passing strings was the only option at the beginning (at least in Firefox). I can imagine they don't restrict passing strings to not brake compatibility... couldn't find much else for why (yet). – Felix Kling Commented May 21, 2011 at 12:13
- 1 @Felix: Indeed, I was looking for that part in the docs, too. Interesting that an obvious spelling mistake actually makes your statement even more valid (‘brake’ should be ‘break’). ;-) – Marcel Korpel Commented May 21, 2011 at 12:24
- "If it isn't, why is it even allowed?" - this is definitely not the only thing in JavaScript that is never useful and evil, yet allowed... – The Paramagnetic Croissant Commented Aug 12, 2014 at 8:17
2 Answers
Reset to default 17You can always use global variables by accessing them as properties of the window object, like window.globalVar
(though using globals is indeed not a good practice), so no, I don't think there is ever a good reason to use the deprecated syntax.
It is probably allowed for historical reasons: as Felix Kling mentioned, the original syntax did only allow to pass a string of code:
Introduced with JavaScript 1.0, Netscape 2.0. Passing a Function object reference was introduced with JavaScript 1.2, Netscape 4.0; supported by the MSHTML DOM since version 5.0. [source, my emphasis]
If browsers don't support the use of a string as first argument to setTimeout
and setInterval
anymore, there will be lots of code on the internet that doesn't function anymore.
For those who are redirected here by the question of why is passing a function better than passing a string.
1: Passing a string fires up a compiler
Every time you have to evaluate a string, you fire up a full compiler. For each and every invocation where it is needed.
Not only is this slow, it destroys all of the JIT and browser speedups that are done.
2: Passing a string is MUCH more limited.
Because a string is run through a compiler, it isn't as cleanly bound to the local scope and variables.
While it isn't noticeable in situation like:
window.setInterval("doThing()");
In a more complex situation, the code is just cleaner:
window.setInterval("doThing(" + val1 + "," + val2 + ")");
vs
window.setInterval(function() {
// You can put a debugging point here
dothing(val1, val2);
});
3: DOM objects can't be passed via string
As Álvaro mentioned, DOM objects can not be passed via a string method.
// There is no way to do this via a string.
var el = document.getElementById("my-element");
window.setInterval(function() {
dothing(el);
});
(Other objects may or may not be passable -- depending on if they can be serialized, but but in general it would be quite difficult.)