javascript - javascript functions - Programming Languages - Tech tutorial

Immediately invoked function expressions (IIFE) in JavaScript

An immediately invoked function expression, or IIFE (pronounced iffy), is a function that is called immediately after it is defined.

While it may seem peculiar, creating functions that behave in such a way can actually benefit the code that we write. Before we look further, let’s first take a look at what function expression looks like in JavaScript.

Function expressions.

Recall that in JavaScript, functions are treated as first-class objects. This means that you can do just about anything with a function that you can do with other elements (e.g., numbers, strings, data structures, etc.). For example, functions can be returned from other functions, or even be passed as arguments into another function (i.e., callbacks).

One key feature is the ability for a function to also be assigned to a variable. Consider the following example:

const myFunction = function greeting() {
 return "Hello";
};

In the above example, the value of myFunction is the named greeting() function. The same function expression can also be written anonymously (i.e., not named) as well:

const myFunction = function () {
 return "Hello";
};

As a final point, note the contrast between the function expressions above and a function declaration below, which simply defines a function and does not require a variable to be assigned to it.

function greeting() {
 return "Hello!";
}

Though it isn’t strictly required per se, you’ll commonly see function expressions assigned to variables. What’s most important to note is that a function expression is simply a function that is a part of another expression’s syntax.

Syntax.

On the topic of function expressions and syntax, what does an immediately invoked function expression (that is, an IIFE) look like? Here is its signature:

(function functionName() {
 // function logic
})();

To create the IIFE, we first create the function declaration: functionName(). Then, once the function is defined, we:

  1. Wrap parentheses around it. This creates the function expression
  2. Add a second pair of parentheses at the end to immediately invoke it

And that’s the entire syntax! Note that you may also use an anonymous function as part of the IIFE as well:

(function () {
 // function logic
})();

Additionally, you may also see IIFEs written the following way as well, in which the first closing parenthesis is moved to the very end:

(function functionName() {
 // function logic
}());

Much of this is a stylistic choice, and there is no “correct” way of auto-invoking a function. All the syntax above represent valid approaches for achieving the same result, and the JavaScript engine will still parse them each as a function expression (i.e., rather than as a function declaration).

Examples.

Consider the example greeting() function from earlier:

function greeting() {
 return "Hello";
}

To convert greeting() into an IIFE, we wrap the entire function in parentheses, then add another set of parentheses () to invoke it:

(function greeting() {
 return "Hello";
})();


// "Hello"

In the above example,  "Hello" is returned because the greeting() function is invoked immediately after it is defined, as a result of having the second set of parentheses () at the end. 

This second set of parentheses is also the place to enter any arguments that the function may need as well. Consider the following example of an IIFE, this time with an anonymous function:

(function (a, b) {
 return a + b;
})(2, 3);


// 5

As with the other IIFEs above, once the function is defined, it is immediately invoked. As such, when 2 and 3 are passed in as arguments (in the trailing set of parentheses), 5 is returned.

Now that we’ve seen what IIFEs look like, let’s take a look at more practical reasons for including them in the code we write?

Private scope.

One of the primary uses for an IIFE is to create private scope (i.e., private state). Variables in JavaScript are traditionally scoped to a function. Knowing this, we can leverage the behavior of closures to protect variables or methods from being accessed!

Consider the following example of an IIFE:

const counter = (function () {
 let count = 0;


 return function () {
   count += 1;


   return count;
 };
})();

In the above example, an immediately-invoked function expression is used to immediately run a function. This function runs and returns an anonymous function that is stored in the counter variable.

Note that the function that is being returned forms a closure over the count variable. This allows counter, which points to the returned inner function, to maintain a private, yet mutable state that cannot be accessed outside the function! As such, we can call the function to increase the value of count:

counter(); // 1
counter(); // 2
counter(); // 3

And at the same time, count is inaccessible by anything other than the IIFE itself:

count; // Uncaught ReferenceError: count is not defined

Overall, there is no way that count can be read or modified outside of the returned function. And as an added benefit, this also helps minimize pollution of the global environment, hindering the chances of variable name collisions. This is all due to the private scope created through the IIFE!

Learn more about IIFEs.

For more information about immediately invoked function expressions (IIFE), check out these resources:

Or explore the Intermediate JavaScript Nanodegree program to master the most popular programming language in the world.