Is there ever a good reason to pass a string to setTimeout?


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...

You 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.)