Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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

like image 826
lonesomeday Avatar asked May 21 '11 11:05

lonesomeday


People also ask

Is setTimeout reliable?

The setTimeout function is okay, but overall, for a 250ms theoretical timeout, the real/effective timeout value ranges from 251ms to 1.66+s. As of October 2020, the most accurate way of scheduling a function/callback is using the setTimeout function in a Web Worker , in a cross-origin iframe.

Is setTimeout deprecated?

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);

Does setTimeout affect performance?

No significant effect at all, setTimeout runs in an event loop, it doesn't block or harm execution.


2 Answers

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.

like image 159
Marcel Korpel Avatar answered Sep 21 '22 20:09

Marcel Korpel


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

like image 42
Jeremy J Starcher Avatar answered Sep 22 '22 20:09

Jeremy J Starcher