In Javascript, an IIFE stands for an Immediately-Invoked Function Expression: a function expression that gets invoked immediately after it is defined, such as (function(){ /* code */ })();
IIFE stands for Immediately-Invoked Function Expression. It is used mainly to describe the pattern in JavaScript where a function expression is executed immediately after it is defined. IIFEs usually have the following syntax in JavaScript:
(function() { /* code */ })();
But there are several other valid ways to form an IIFE mentioned in this answer, such as
(function() { /* code */ }());
new function(){ /* code */ }();
The term IIFE was first proposed by Ben Alman in this article, in which he suggests the pronunciation "iffy". He proposed this term as an alternative to what he calls the "popular but misleading term self-executing anonymous function".
The most common notations used today are (function(){}());
, with the invoking parentheses inside the grouping ()
, and (function(){})();
, with the invoking parentheses outside of the group.
Apart from there being a minor semantic difference between the two (the first evaluates to (returnvalue of IIFE)
, whereas the second evaluates to (defined function)<=(call)
) they are both equally valid, though the renowned JavaScript expert Douglas Crockford considers the second notation as being "wrong" and "illogical":
When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself.
From Code Conventions for the JavaScript programming Language.
The term IIFE was rapidly adopted by the community after it was first coined at the end of 2010. Simply because it's the most accurate description of the pattern itself:
- II (Immediately-Invoked): The function is defined, and invoked in one go. That's pretty clear
- F (Function) It's a function...
- E (expression): Not just any old function: it's an expression rather than a statement. This is crucial.
The difference between a function definition and a function expression is where the function is defined (sticking to JavaScript for examples).
// Any old function:
function f(arg)
{
return arg;
}
This function definition will be hoisted to the top of its scope, and be made accessible all over that scope:
console.log(f(123));
function f(n)
{
return (typeof n);
}
will neatly log number
, even though the function seems to be called prior to it being defined.
By turning the function into an expression, the definition cannot be hoisted:
console.log(typeof f);
var f = function()
{
return 'something';
};
console.log(typeof f);
In this example, the only thing that will be hoisted is the declaration of the variable f
. The function definition itself is an expression, in the shape of the right hand operand of an assignment. Assignments are never hoisted, so the code will log undefined
, and then function
.
To turn this Function Expression into an IIFE, we have to do two things: Make sure the function definition is an expression, rather than a statement. As explained above, this is achieved by wrapping the function in the grouping ()
operator, or adding a logical- or bitwise operator to the statement, the void
prefix or the new
keyword.
Notes:
Using the void
prefix effectively suppresses the return value of the IIFE, and always returns undefined
:
var foo = void function()
{
console.log('called');
return 'returnVal';
};
console.log(foo);
Logs called
, and then the value of foo
-> undefined
.
Using the new
keyword will affect the call-context (this
reference) of the IIFE_: The IIFE will behave as a constructor, returning a new object:
new function()
{
return this.constructor;
};
will return a reference to the function that was just called.
Specific use cases:
- IFFE's are often used when passing a function as an argument to another function (most notably to solve the infamous loop problem)
- Custom constructors often are wrapped in an IIFE, to allow for pseudo (private-) static properties. Variables declared in the IIFE's scope stay in memory for as long as the return value of that IIFE is referenced somewhere. This return value can be an object, with a function that in turn references variables from the IIFE's scope. Here's an example.
- In some browsers, older versions of Internet Explorer in particular, attaching event handlers directly to DOM references caused memory leaks, owing to Internet Explorer managing the memory for the DOM and its JScript engine separately. The only way around this is to attach listeners in an IIFE. When the script terminates, the GC (Garbage Collector) can flag & swipe the entire IIFE's scope and, with it, all DOM references and event handlers are deallocated.
- Certain patterns, like the module pattern, requires an IIFE. In this function, the module is built up, and eventually exposed (by assigning a global variable) or returned.
- Sometimes, the entire script is wrapped in an IIFE, to avoid global variables. This is, however, considered a quick-'n-dirty fix.