16

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?

qwertymk
  • 34,200
  • 28
  • 121
  • 184

5 Answers5

27

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.

Mark
  • 626
  • 5
  • 20
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • Third option is only when there are no arguments – qwertymk Dec 22 '10 at 04:13
  • @qwertymk - that's correct, but there are none in your examples (and *most* of the time you see this out in the wild, there also aren't). – Nick Craver Dec 22 '10 at 04:14
  • Actually you can use setTimeout(func, 100, arg1, arg2, ...) if you want to, but in that case my choice, the string wins in terms of readability: setTimeout("func(arg1, arg2, ...)", 100). – martona Dec 22 '10 at 04:16
  • @qwerymk, @martona, the syntax with extra arguments doesn't work with IE. – dheerosaur Dec 22 '10 at 04:18
  • The semi-colon issue has come up again recently, and it's fair to say the author of the following does disagree with @Nick: http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding – Tim Down Dec 22 '10 at 11:23
  • [http://jsperf.com/settimeout-func-vs-function-func-vs-func](http://jsperf.com/settimeout-func-vs-function-func-vs-func): [http://i.imgur.com/tGsOn.png](http://i.imgur.com/tGsOn.png). Yeah... I don't know. – Hello71 Jan 27 '11 at 03:33
11

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.

user1629060
  • 566
  • 6
  • 6
5

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

Adarsh Konchady
  • 2,577
  • 5
  • 30
  • 50
2

People you mentioned use it probably not because it is faster.

  • code in the alternate syntax, is a string of code you want to execute after delay milliseconds. (Using this syntax is not recommended for the same reasons as using eval())

From https://developer.mozilla.org/en/DOM/window.setTimeout

dheerosaur
  • 14,736
  • 6
  • 30
  • 31
0

I don't think either one is measurably faster in modern browsers. Even if one were somewhat faster, the mere fact that your code won't call setTimeout too frequently makes the point moot.

The first one has the benefit of being more readable, and would be my preference.

martona
  • 5,760
  • 1
  • 17
  • 20
  • 2
    The string might be slightly more readable, but it's *much* more unsafe. – Greg Hewgill Dec 22 '10 at 04:18
  • Well... if you're going to make your UI work by prompt()-ing the user for the function to call, or making a HTTP request for the function name, then yeah, it's unsafe. – martona Dec 22 '10 at 04:22