14 responses to “Passing arguments to javascript’s setTimeout() method using closures”

  1. Thomas

    There’s an easier way to do this:


    ...
    var msg = "Hello World";

    setTimeout(doAlert, 1, [msg]);
    ...

    function doAlert(msg)
    {
    alert(msg);
    }

    There’s no need for the delay function.

    Furthermore, when passing a reference to a function as the first parameter to the setTimeout method, you’re supposed to pass the reference to the function, not a call to the function.

    e.g.

    // passing a call to the function is incorrect
    var t = setTimeout(someFunction(), 1, argsArray);

    vs.


    // passing a *reference* to the function is correct
    var t = setTimeout(someFunction, 1, argsArray);

    Enjoy,

    Thomas

  2. John

    Good comment by Thomas and while I accept your authority on this you’re about the only person out there defining the call this way. Most of the examples I’ve seen pass a “call to the function” and do so in quotes! ie:

    setTimeout(‘someFunction()’,etc)

    And one reference (I can’t remember where) defines that third parameter as an optional definition of the language of the called function!

    Your solution works, of course.

  3. John

    Follow-up:

    Well, it seems as though you’re right and wrong Thomas. Firefox does subscribe to what appears to be the standard

    https://developer.mozilla.org/En/DOM/Window.setTimeout

    but IE, of course does not. Thomas’ syntax doesn’t work on IE7 (I tried it).

    An alternative–but less elegant–solution that works in both browsers is to frame the called function/parameters in quotes, thus:

    function called(a,b) {
    alert(a+”-”+b)
    }
    function caller(a,b) {
    setTimeout(‘called(‘+a+’,'+b+’)',2000);
    }

    Later code ….
    caller(1,2);caller(3,4)
    Will show alerts of “1-2″ and “3-4″ after 2 seconds.

  4. archerid

    This was incredibly helpful. I’ve spent an embarrassingly long time trying to track down the right way to pass params through setTimeout. Thanks for posting your method.

  5. Trev

    Another version that seems to work is simply:

    setTimeout("doAlert("+msg+")", 1);

    Might get a bit confusing with multiple arguments mind you, but works in IE8, FF3 and Chrome (so presumably also in Safari). Not got IE7 to test it on however.

  6. Kevin

    Old news now, but Thomas is correct. setTimeout accepts a function object in the first argument, not a javascript call. Therefore I would have thought the simplest cross-browser method of passing arguments is to do it via an anonymous function definition:

    var msg = “Hello World”;

    setTimeout(function(){alert(msg)}, 1);

  7. alex

    Thomas, thanks…. Great solution!.

  8. Çağlar Or

    setTimeout can not be clear via clearTimeout (Or setInterval, clearInterval) from the called (closured) function. Is it an exception or anything?

  9. Andrew Urquhart

    Everyone seems to have missed the simple answer to “having your cake and eating it”. Simply wrap the delayed function you wish to call inside a new anonymous function like so:

    setTimeout(function(){alert(msg)}, 1000)

    Now you can pass arguments to functions without using strings, alternative functions or script that doesn’t work cross-browser :)

  10. bruno

    Thx for the tip, very usefull.

  11. Dan Nielson

    Hmm… Ok, so I know this is an old post, but it comes up as the top ranking result for Google searches about passing arguments to setTimeout and is one great big misunderstanding of how this function works.

    Thomas was not partially correct. He was correct. At least in as far as Javascript is concerned. The real issue is that IE doesn’t use Javascript. It uses JScript which is only ‘Javascript Compatible’ and not an actual Javascript implementation which, as seen here, can cause some unexpected behavior exclusive to IE.

    Now, by passing the function call to setTimeout, the function is running BEFORE setTimeout is called and the only thing being delayed is the result of the function. Therefore:
    ——————————————
    var a =1; var b=2;
    function add_a_b(){ return a+b; }
    setTimeout(add_a_b(),1000);
    a=3;b=5;
    ——————————————
    returns 3 not 8 as calling setTimeout(add_a_b,1000) would do. The reason being that the first example calls add_a_b and passes the result to setTimeout, while the later tells setTimeout to call add_a_b in 1 second which is after the reassignment on the fourth line.

    Finally, passing a string containing the function call isn’t good. The only way javascript can run that string, is to use eval(). A function which is generally considered to be ‘evil’. In other words, eval opens up myriad security holes and creates a tremendous amount of overhead on the function call(which increases exponentially with the complexity of the string) as you’re essentially using javascript to interpret javascript.

    In short, closures are more efficient then passing a string to setTimeout, and much safer too. Especially if your Javascript code is running in a server environment using something like node.js.

  12. Yves

    Thank you for
    1. emphasizing the fact that we sadly *have* to support IE ; it always has been a pain, it always will unfortunately (for another decade probably)
    2. the closure solution (all browsers incl. IE) allowing to solve the “this” problem as well (passing “this” as an argument like
    var me = this;
    var delay = function() { me.doAlertThroughInstance(msg); };
    setTimeout(delay, 1000);
    ).

  13. SetTimeOut dans ie avec arguments « nomood

    [...] = $(this).val(); var delegate = function(){rechercheProjet(filtre);}; setTimeout(delegate, 1000 ); Source Share this:TwitterFacebook"Aimer" ceci :"J'aime"Soyez le premier à aimer [...]

  14. extremejava

    You saved my way. The method given in the post is working but all other methods in the comments are not working.

    I tested on IE6,7,8,9 and FF7,8,9 so for cross browser support, follow what is there in the post else break your code.

    Java Programming Tutorial

Leave a Reply