Interestingly enough I get asked about the IIFE (immediately-invoked function expression) a lot, which takes the following setup:
So why not write a post about it? ;-)
First, this does a series of different things. From the top:
function scope, so first this creates some much needed “private scope”. For example:
How it works
A normal function looks like this:
We get to invoke it by choice, and wherever we want/can scope providing.
The reason “IIFE” was coined was because they’re immediately-invoked function expressions. Which means they’re immediately called at runtime - also we can’t call them again they run just once like this:
The secret sauce here is this, (which I’ve assigned to a variable in the previous example):
The extra pair of parentheses is necessary as this doesn’t work:
! character as an expression:
There are also other variants:
But I wouldn’t use them.
Now we know how it works, we can pass in arguments to our IIFE:
How does this work? Remember, the closing
(window); is where the function is invoked, and we’re passing in the
window Object. This then gets passed into the function, which I’ve named
window also. You could argue this is pointless as we should name it something different - but for now we’ll use
window as well.
So what else can we do? Pass in all the things! Let’s pass in the
Local variables are faster to resolve than the global variables, but this is on a huge scale and you’ll never notice the speed increase - but also worth considering if we’re referencing our globals a lot!
In ECMAScript 3,
undefined is mutable. Which means its value could be reassigned, something like
undefined = true; for instance, oh my! Thankfully in ECMAScript 5 strict mode (
'use strict';) the parser will throw an error telling you you’re an idiot. Before this, we started protecting our IIFE’s by doing this:
Which means if someone came along and did this, we’d be okay:
Minifying your local variables is where the IIFE pattern’s awesomeness really kicks in. Local variable names aren’t really needed if they’re passed in, so we can call them what we like.
Imagine it, all your references to libraries and
document nicely minified. Of course you don’t need to stop there, we can pass in jQuery too or whatever is available in the lexical scope:
This also means you don’t need to call
jQuery.noConflict(); or anything as
$ is assigned locally to the module. Learning how scopes and global/local variables work will help you even further.
A good minifier will make sure to rename
c (for example, and only if used) throughout your script too. Important to note, the name undefined is irrelevant. We just need to know that the referencing Object is undefined, as
undefined has no special meaning -
Non-browser global environments
Due to things such as Node.js, the browser isn’t always the global Object which can be a pain if you’re trying to create IIFE’s that work across multiple environments. For this reason, I tend to stick with this as a base:
In a browser, the global environment
this refers to the
window Object, so we don’t need to pass in
window at all, we could always shorten it to
I prefer the name
root as it can refer to non-browser environments as well as the root of the browser.
If you’re interested in a universal solution (which I use all the time nowadays when creating open source project modules) is the UMD wrapper:
This is some sexy stuff. The function is being invoked with another function passed into it. We can then assign it to the relevant environment inside. In the browser,
root.MYMODULE = factory(); is our IIFE module, elsewhere (such as Node.js) it’ll use
module.exports or requireJS if
typeof define === 'function' && define.amd resolves true.
But this stuff is another story, but I insist you check out the UMD repo.