1

I used

setTimeout('InitData()', 100);

but JSHint tells me "using a function is better then a string" and I changed it to:

setTimeout(function () { InitData() }, 100);

But why is it so?

PassionateDeveloper
  • 14,558
  • 34
  • 107
  • 176
  • see heer http://stackoverflow.com/questions/17080318/how-to-pass-parameters-to-settimeout-function – Mritunjay Aug 12 '14 at 07:49
  • The string approach looks like a hack for delayed execution. In JS this is not necessary, because functions are first-class citizens that can be used as function arguments. – Sebastian vom Meer Aug 12 '14 at 07:49
  • The reason becomes obvious as soon as you start passing arguments. – Álvaro González Aug 12 '14 at 07:51
  • Another related question: [Is it bad practice to pass a string to settimeout? If yes, why?](http://stackoverflow.com/questions/6232574/is-it-bad-practice-to-pass-a-string-to-settimeout-if-yes-why) – Ram Aug 12 '14 at 07:51

1 Answers1

3

There are a couple of reasons.

  1. Primarily, when you pass setTimeout a string, the string is evaluated in the global context. That means that the function it calls has to be a global function. Avoiding globals is good practice.

    For instance, this fails: Live Example (see error in the console)

    (function() {
       "use strict";
    
       setTimeout("display('hi');", 0);
    
       function display(msg) {
         var p = document.createElement('p');
         p.innerHTML = String(msg);
         document.body.appendChild(p);
       }
    })();
    

    ...because display is not a global function.

    But this works: Live Example

    (function() {
      "use strict";
    
      setTimeout(display.bind(null, 'hi'), 0);
      // Or:
      // setTimeout(function() { display('hi'); }, 0);
    
      function display(msg) {
        var p = document.createElement('p');
        p.innerHTML = String(msg);
        document.body.appendChild(p);
      }
    })();
    
  2. Using a function reference rather than a string means we're using the same semantics we use just about everywhere else we use callbacks, rather than making calling setTimeout some weird special thing. For instance, the way I give addEventListener a function to call when an event occurs is the same way I give setTimeout a function to call when it times out. Consistent semantics help to avoid errors.

  3. Using a function reference rather than a string lets me be very specific about what function I'm calling. Consider:

    function showInASecond(str) {
      setTimeout(function() {
        alert(str);
      }, 1000);
    }
    

    I couldn't reasonably use a string there. Oh, I could try to create a concatenation, being sure to escape everything I'd have to escape in the str (like quotes, backslashes, and such), but simple is better.

  4. If you pass setTimeout a string, it has to fire up a full JavaScript parser to evaluate it. Not much of an issue, but still more work than required.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875