MakeMineATriple

Passing parameters to a function called with setTimeout

Posted on 18 October 2007 by bryan

When creating my news ticker plugin, I came across a slight complication when using setTimeout() to calling a function which needed parameters passed to it. Not having had much call to use setTimeout in the past, I simply put:

setTimeout(myFunction(parameter), myTimeout);

but that doesn’t work. An apparent solution (until tried in Internet Explorer) is:

setTimeout(myFunction, myTimeout, parameter);

It wasn’t as easy as I expected to find out how to get around this, but it turns out that all is needed is a “closure”:

setTimeout(function(){myFunction(parameter)}, myTimeout);

Comments (133 so far)

Closures are arguably the great secret of Javascript: the way variable scope stacks get frozen at the point of closure (and hence variables persist within the closure) is quite subtle and catches most out, including me!

Be warned that IEx has a garbage-collector subtlety, though; I think that if you reference a DOM variable in a Javascript closure, then the collection mechanism gets confused and it doesn’t get trashed at the end of the request: eventually this becomes a memory leak. I think it’s because DOM variables and internal JS variables get collected by two different collectors, and they don’t communicate properly about what’s no longer being used.

I think you can fix this by setting the variable to null:

setTimeout(function(){myFunction(parameter); parameter = null},myTimeout);

This explicitly sets the garbage collection in motion.

J-P Stacey 29 Oct 2007 - 10:15

Thanks for that, J-P - I agree they seem to be rather a secret! I’ve added this into the news ticker and put up the new release

bryan 31 Oct 2007 - 05:37

I was pulling my hair out. The books seem to gloss over this like I should have known it and then go on to tell me some obscure thing I’ll never use. I cannot thank you enough!

Greg 07 Nov 2007 - 02:47

This is great. I was getting rather frustrated with IE not accepting the 3rd parameter and could not find a way around it for my code. Now I dont have to.

Matt 07 Aug 2008 - 08:25

Great tip!! I’ve been looking for this solution for a while now. Thanks!

Jake 13 Aug 2008 - 03:47

Thanks for the tip, I found a couple of other solutions which were not idea. The first was to make the function in a string (does not work for objects). The second from M$ was to use global variables (bad bad bad).

Thanks again, you are no bookmarked!

Ergin 17 Sep 2008 - 14:23

This was very helpful! I was looking for this solution everywhere!

Thanks

Chris 07 Oct 2008 - 20:17

[…] the ‘variable = null’ is to stop a memory leak as the variable is not deleted as it should be (thanks makemineatriple) […]

great reminder … closure is the answer …

willowdan 26 Nov 2008 - 10:53

Thanks for the tip!

Rico

Rico 26 Nov 2008 - 16:22

Thank you!

Not only did you give a lucid explanation of this setTimeout dilemma, you cleared up the ‘closure’ concept for me. All in 100 words or less.

I have several other ‘tutorials’ and they all dove headfirst into ‘here, look at this code’ and never got around to the heart of the matter.

Don Bevis 06 Dec 2008 - 03:20

Don’t want to spam, just to say a sincere Thank you!

Viper 06 Dec 2008 - 23:00

Thank you. Cannot express my feeling in words. I was getting no where since last 2 days and this blog made my day.
Thank you. You Rock!!

Ankit Bansal 17 Dec 2008 - 14:06

Great tip!! I’ve been looking for this solution for a while now. Thanks!

coolpositive 08 Jan 2009 - 12:32

Thanks a lot! I’ve been googeling for hours for this solution.

Esger 03 Feb 2009 - 23:57

Thanks a lot.
F*ck Explorer.

cadeyrn 05 Feb 2009 - 15:20

[…] (thanks makemineatriple) […]

Thank you very very much.

AV 23 Feb 2009 - 16:40

Well done buddy!
You ARE the man - thanks. Victor.

Victor 27 Feb 2009 - 16:23

Great article! saved me a lot of time.
Thanks a lot!!

Dave 02 Mar 2009 - 17:24

Great help! Thanks a lot!! Searched a solution for a whole day..Finally got it :)

Sangeetha 09 Mar 2009 - 12:15

I found something else that seems to work. Whenever I use setTimeout, the syntax looks like this:

setTimeout(“Myfunction(parameter)”,timeout)

For me what’s evolved is the manipulation of the string part of the function—the new function and parameter(s), which are in quotes. I can pass a parameter by writing the function like this:

setTimeout(“Myfunction(” + parameter + “)”, timeout)

Seems to work fine, at least at this point. Anybody have any comments on this?

Rick 13 Mar 2009 - 17:00

@Rick,

Maybe I’ve misread something, but the following code doesn’t work, while the commented-out line, which uses the closure, is fine:

$(document).ready(function() {
var p1 = 'one';
var p2 = 'two';
//setTimeout(function(){test(p1,p2);},400);
setTimeout("test("+p1+")", 400);
});

function test(param,param2) {
alert(param);
alert(param2);
}

I’d suggest that, any other considerations aside, the closure approach is more manageable syntax, particularly where several parameters are needed.

Bryan

bryan 28 Mar 2009 - 05:38

Thanks a bunch partner. I had been searching for this for a couple of hours. Whoa, got to git back to the ranch.

Cowboydan 07 Apr 2009 - 23:28

You are top result for this google query:

javascript pass parameters to setTimeout

THANK YOU for being top result!

Funny enough I’d done what you did but wasnt sure why it was working, and was looking for the “proper” way to do it… I guess this was the proper way!

BladeMcCool 09 Apr 2009 - 20:39

Finally! OMG! Thanks!

Anonymous 10 Apr 2009 - 05:15

@23 Bryan,

That code is never going to work because you have not written it correctly.

Look at setTimeout(“test(“+p1+”)”, 400);
expand it yourself and you get

setTimeout( test(one), 400);

test(one) is not valid syntax - unless one is defined as a variable - which it is not.

You probably meant setTimeout(“test(’ “+p1+” ‘)”, 400);
Where there are some extra quotes to yield test(‘one’).

Even then, it probably doesn’t do what you expect.

gazhay 01 Jun 2009 - 16:25

@gazhay - you’ve misread my comment:

I declared that the code posted *didn’t* work (in response to Rick - comment 22), but that using my commented-out line *does* work.

bryan 03 Jun 2009 - 21:11

Thank you this helped solve a three day problem. As a note if you need to use the keyword ‘this’ it still doesnt work in the closure, you have to create a variable reference to ‘this’ (eg. var myThis = this;). Thanks again

Sam Hill 30 Jun 2009 - 19:17

Hey Guys,

Just found another neat solutions. This code structure looks more normal and you don’t have to us the idea of closures.

setTimeout(”test(‘”+p1+”’)”, 400);

The ‘”+ param +”’ is what allows parameters from the outside of the inner function to be read. I guess with the ” there the ’ escapes the “. Hope this helps.

Ramon 24 Jul 2009 - 14:26