setTimeout() with string or (anonymous) function reference? speedwise [closed]

Which one of these two ways is faster and why?

window.setTimeout("func()", 100);

Or

window.setTimeout(function(){func();}, 100);

I'm guessing the second way is faster if for no other reason other than John Resig and all the ninjas use it, I'm guessing because it already parsed as opposed to the first way which it would have to create a new parsing "thingie". I vaguely recall this being one of the reasons people don't like eval().

Also while I have you here, in the second code snipplet, is the first semi-colon considered good practice in such a case?


Solution 1:

There's a third faster/simpler option:

window.setTimeout(func, 100);

...strictly relating to your question, the second is faster, as it's still a reference - not an evaluation, which is always fairly expensive. As for the semicolon, yes it's a good practice to always use them. They should never have been optional in my opinion, but plenty will disagree with me here. You can't really argue against being explicit in your code, that's always a good thing.

Solution 2:

As you've written it, both are equally "safe". The safety issue comes up when you try to pass arguments, because there is a temptation to do things like this:

setTimeout('func('+arg+')', 100);

Which has the potential for code injection. Someone will use it to destroy your death star. Sooner or later, a young jedi will figure out how to trick your app into making arg equal to 3.14); deathStar.selfDestruct(, and next thing you know, you're getting a call from the Emperor to explain your mistake.

And it might not be you who makes the mistake... you would never do anything so foolish. When your code gets refactored 6 months later by the intern and they need to add an argument, that's when the problem comes.

So the string form is just considered bad practice. It's slower, and potentially less safe.

Solution 3:

Using 'setTimeout' with string syntax internally makes the javascript engine 'eval' it. Whenever the browser encounters an 'eval' anywhere in the code, it cannot do many of the optimizations (and hence disables them) just because anything can get into eval.

Optimizations such as caching variables cannot be done with 'eval' existing in the code because 'eval' may introduce new variables which will get ignored during the compilation phase of Javascript (where it detects all the declarations).

The second syntax is faster because it will just call the function after the delay and you won't get into the evils of 'eval'.