Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at CFUNITED 2009 (Lansdowne, VA) with:

Using Named Functions Within Self-Executing Function Blocks In Javascript

By Ben Nadel on

This is just a quick tip that I recently picked up from watching Paul Irish discuss 10 things that he learned from the jQuery source code. It was a couple of weeks ago, but I don't believe that this tip was actually something in the jQuery source code; rather, I believe it was just something that he demonstrated in one of his explantations. Anyway, what he showed me was that you could use named functions in self-executing function blocks.

Typically, when we we create a self-executing function block, we do so with an anonymous (lambda) function:

  • ( function(){ .... function body .... } )();

This works great - it takes the anonymous function and executes it immediately. As Paul demonstrated, however, the same thing can be done with a named function:

  • ( function myFunction(){ .... function body .... } )();

While this additional variable reference - myFunction - is not always needed, it does provide us with a way to create recursive, self-executing functions. In the following demo, I've created a self-executing function that increments a counter, logs it, and then calls itself recursively:

  • <!DOCTYPE html>
  • <html>
  • <head>
  • <title>Named Self-Executing Functions</title>
  • <script type="text/javascript">
  •  
  • // Define a variable to be accessed within the
  • // self-executing function block.
  • var counter = 0;
  •  
  • // Create a self-executing function block; however, rather
  • // than passing in an anonymous, headless function, let's
  • // pass in a named function.
  • (function useCounter(){
  •  
  • // Increment and log counter.
  • console.log( ++counter );
  •  
  • // Call *this* function again in after a short timeout.
  • // Since it has a name, we don't have to use the
  • // depracated arguments.callee property.
  • setTimeout( useCounter, 1000 );
  •  
  • })(); // Self-execute.
  •  
  • </script>
  • </head>
  • <body>
  • <!-- Intentionally left blank. -->
  • </body>
  • </html>

As you can see here, we have defined the function, useCounter(), as the target of the self-executing function block. The logic, within this self-executing function, then executes the useCounter() function recursively after a brief timeout. After letting this page run for a few seconds, I get the following console output:

1
2
3
4
5

As you can see, the self-executing behavior of the function block is exactly the same; but, we gain the added benefit of being able to reference the function in question without having to rely on deprecated features such as "arguments.callee." A small but awesome tip from Paul.



Looking For A New Job?

100% of job board revenue is donated to Kiva. Loans that change livesFind out more »

Reader Comments

I do this slightly differently.

functionName = (function(){ ..do stuff.. })();

same thing really.

Reply to this Comment

This approach is pretty great - I'm a fan.

I picked it up from this gist from Ben Alman (which itself was forked from a gist from Remy Sharp), which shows some other ways to use this technique (such as waiting before the first execution or using setInterval instead of setTimeout).

Also, given that you're using the HTML5 doctype, you can drop the type attribute from the script tag. It felt weird at first, but I'm enjoying not having to bother with that now. :)

Reply to this Comment

Naming your anonymous functions is also nice because those names show up in stack traces when you debug in tools like Firebug. Seeing descriptive names there makes a world of difference when you're debugging something a few callbacks deep.

Reply to this Comment

@Liam,

Hmmm. I might be missing something, but I cannot get that to work for me. When I do this:

var foo = (function(){ alert( "bar" ); })();
foo();

... only the initial alert() works; the second one errors out that "foo" is undefined.

Typically, when I need to get "a" callback from the self-executing function, I need to explicitly return it:

var foo = (function(){ return( ..fn.. ); })();

... am I missing something?

@Brian,

Thanks for the link. Ben Alman definitely has a lot of great stuff! I'll be sure to check out the gist. As far as removing the "type" attribute from the Script tag, the only reason I want to shy away from that is that I actually use Script tags for other types as well (ex. type="text/template").

@Dave,

Oh cool - I hadn't even thought of that.

@Hal,

My pleasure - always happy to pass on some good stuff I get from others.

@All - a quick follow up on the concept in the context of method callbacks:

http://www.bennadel.com/blog/1989-Using-Named-Callback-Functions-In-Javascript-Methods.htm

Reply to this Comment

@Ben: forgot to mention that it needs to be inside an object. I tend to keep all my functions inside of a global object.

obj = {};
obj.funcName = (function(){ alert('hi'); })();

Reply to this Comment

hi Ben,

(
function s()
{
alert("moh");
}
)();
s();

this code do well in IE,
but doesn't work in my FireFox 3.6.8 and my opera 10

in FF it says 's' is defined in last line of the code above.

is it my fault? or something problem with the browsers.

Reply to this Comment

@Mohsen,

This is my experience as well. I think the self-executing block creates a kind of self-contained scope. You could probably do something like this:

var s = (function s(){ .... return(s); })();

The "return(s);" should return the local "s" reference to the calling scope, variable.

Reply to this Comment

This will work as you expect since the "calling" scope for the self-executing anonymous function is the global scope:

var foo = null;
(foo = function(){ alert( "bar" ); })();
foo();

Reply to this Comment

Just to confirm your answer about 's' is correct where the self-invoking function s has its own scope and is passed back to the global scope var s. This will also alert 's' twice as you expected:

var s = (function s(){alert('s'); return s;})(); s();

Self-invoking functions are best for once-off/initialization tasks so normally you would not return the function.

Reply to this Comment

@Johans,

It's an interesting thing; I just read an article posted on related blog entry about the difference between function definition and function expressions. I wonder if this comes into play here?

Anyway, thanks for pointing out that a reference to the method can be assigned within the (..) expression.

Reply to this Comment

Hiya Ben,

I just found this after a Googling 'named self-executing functions' (I had tried 'named immediately-invoked function expressions', but Cowboy's post coining that expression was the only truly relevant hit - for the record, I'm on his side ;).

I use these for the same reason you mention - ie you may want to recurse (as arguments.callee is being deprecated this reason is all the more valid) - but also, as Dave points out, because I like to name all my functions for the sake of stack tracing during debug.

Reason I Googled was because my implementation kept on getting screwed. If I might just explain the fringe case:

I don't like finishing lines with semi-colons - to my overbearing design sensibilities they make the code harder to read, and if you're bracketing and coding properly they shouldn't be necessary. Well, this can be one such case: If the previous statement isn't cut off with a semi-colon, a named immediately-invoked function expression immediately afterwards will cause a type error: previous block is not a function (or something to that extent) - even if the previous block is a function.

This doesn't happen if the function is anonymous, or if it's self-invoked by means of a preceding unary operator rather than enclosing parens. So:

  • /* Fine */
  • invocation()
  • (function(){}())
  •  
  • /* Fine */
  • invocation()
  • ~function name(){}()
  •  
  • /* TypeError */
  • invocation()
  • (function name(){}())
  •  
  • /* Fine */
  • invocation();
  • (function name(){}())

Just thought I'd share that little tidbit with y'all in case somebody lands here with the same problem I had… ;)

Reply to this Comment

Hi Ben,

you forgot to mention the most important thing for named self-executing functions - they can be referenced by name ONLY inside their execution context (which is parens in this case), it means to be called by name only inside itself, recursively. Exactly the case you described.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.