Deep Dive Into Immediately Invoked Function Expressions (IIFEs)

Note: This post is work-in-progress learning-note and still in active development and updated regularly.

In the previous learning-note posts, JavaScript (JS) functions: the basics, callback functions, declaration vs expression were discussed in detail. In this learning-note post, we will deep dive into another important function called the immediately invoked functions expressions (IIFEs) and discuss its basic syntax, writing a basic IIFE with explanation of its each component and brief use cases.

The immediately invoked functions expressions (IIFEs), which is pronounced as “iffy“, is defined on MDN as  “JavaScript function that runs as soon as it is defined“. The IIFEs are also refereed as a Self-Executing Anonymous Function too.

JS Functions – A Brief Review

The JS function is defined on MDN Documentation as ” a code snippet that can be called by other code or by itself, or a variable that refers to the function. When a function is called, arguments are passed to the function as input, and the function can optionally return an output.

Different types of functions:

Js function may have a name or no name. To quote the MDN, “a function name is an identifier declared as part of a function declaration or function expression. The function name’s scope depends on whether the function name is a declaration or expression.

1. A function with a name is named function:

//basic syntax - function declaration
function funcName() {
 //code block
};
//invoke function
funcName();

//ES6 arrow function syntax
let funcName = () => { .. };

2. A function without name is anonymous function:

//basic syntax -anonymous
function () {
 //code block
};
//ES6 arrow function syntax
() => { .. }; //empty function

The code snippets above shows a basic function definition without a function name (anonymous). Since anonymous functions can’t be called by itself, its return has to be stored in a variable, a method known as function expression. In a previous post, a detail discussion on JavaScript Functions – Declaration and Expression is covered.

An anonymous function (without name) are defined using function expression, where function name can be omitted.

// Assign value of the function to math variable
let math = function(a, b) {    // anonymous function
    return a + b;
}
// Invoke function to find the math value
math(20, 100); // OUTPUT => 120

In the example above, the return of function is stored in a var math (line 2) and by invoking the var math (with arguments in any) returns function output (line 6).

Anonymous function can also invoked if there provided as part of another function, as shown in the example below:

//anonymous function definition
window.setTimeout(function() {
    console.log("My anonymous Function!");
}, 1000);
//OUTPUT
My Anonymous Function

In the example above (adopted from Kirupa) the JS built-in setTimeout() method prints the string after 1 second delay without a var name or function name invocation.

3. A function within a function is nested function. The inner function is a function inside another function and outer function is function which contains another function.

//named function declaration
function addSquares(a,b) {
   function square(x) {
      return x * x;
   }
   return square(a) + square(b);
};
//Using arrow notation
const addSquares = (a,b) => {
   const square = x => x*x;
   return square(a) + square(b);
};

In the above example (adopted from MDN) the addSquare function (line 2) is outer function where as square function (line 3) is inner function. The outer function addSquare contains (encloses) square inner function. The same addSquare function is shown with arrow function syntax in lines: 8-12.

4. A recursive function is a function that calls itself. The following example (adopted from MDN) with classic and arrow function syntax:

//named function declaration
function loop(x) {
   if (x >= 10)
      return;
   loop(x + 1);
};

//ES6 arrow notation
const loop = x => {
   if (x >= 10)
      return;
   loop(x + 1);
};

Tip: Recursion s an act of recalling itself and more detailed about recursion in JS is available in the MDN Documentation.

5. An Immediately Invoked Function expressions (IIFE) is a function that is called itself (self-invoking). The following example snippets (adopted from the MDN) explains its basic syntax:

//basic IIFE syntax
(function() {
  let message = "Hello World!";
  console.log(message); 
})();
//OUTPUT (self-invoked)
Hello World!

In the example above, a simple function expression is created with its private variable message and the code is immediately invoked with expected output (line 7). The variable message is not accessible from out of the function.

In this learning-note post, we will explore IIFE in depth within an aim to better understand about

What is IIFE?

Revisiting previous section, where we briefly looked at the IIFEs and lets deep dive into to better understand what is IIFE, how they work? and where to use them?.

The Syntax
//basic IIFE syntax
(function () {
    // code block
})();

The basic syntax of IIFE syntax has two parts. The first part is derived from the anonymous (without name) function that we discussed above with enclosure with the Grouping Operator (). This enclosure secures that variables inside IIFE are not accessible from outside of function thus making them as local variable. The second parentheses ( ) after the expression instructs the JS engine to proceed with execution of preceding function (self-execution).

Lets look an simple working example of IIFE function below:

//define IIFE function
(function() {
  let msg = "Hello World!";
  console.log(msg); 
})();
//OUTPUT (without invocation)
Hello World!

//access var from outside
console.log(msg);
//OUTPUT
Uncaught ReferenceError: msg is not defined

In the example above, the autonomous function is converted into an function expression with the addition of parentheses ( ) after the function (line 6) and the entire function is enclosed with parentheses ( ) , with opening parentheses ( before the function keyword (line 2) and closing parentheses ) after the closing curly bracket } (line 5).

The IIEF function result is accessible but not the function itself as shown below:

//create IIFE function expression
var varStore = (function () { 
    let msg = "Hello World!"; 
    return msg; 
})(); 
// Immediately creates the output: 
console.log(varStore); //OUTPUT => Hello World!

In the example above, the return of the IIFE function is stored in a variable varStore (line 2) and therefore accessible from outside of IIFE function (line 7).

How to Write a Simple IIFE?

In the previous section, we wrote a working IIFE, lets deep dive further into it and understand how an anonymous or function expression is converted into an IIFE?

Step One: Lets revisit our previous anonymous function that we would like to convert into IIFE, as shown below:

//create & define an anonymous function
function() {
  let msg = "Hello World!";
  console.log(msg); 
}
//OUTPUT
Uncaught SyntaxError:Unexpected token

If we run the above function, we get an syntax error (line 7). This is because if a JS function definition is started with function keyword, it must have name, since there is no name – it throws syntax error. JS engine does not know what to do.

Step Two: Lets add parentheses ( ) after the function body {..} to instruct the JS engine to execute the preceding statement immediately.

//create & define an anonymous function
function() {
  let msg = "Hello World!";
  console.log(msg); 
}() // added () parentheses after body
//OUTPUT
Uncaught SyntaxError:Unexpected token

The above code also throws syntax error (line 7) because a function declaration can’t be called (invoked) immediately. Even if we added a name, it still throws error as shown below:

//create & define an anonymous function
function hello() {
  let msg = "Hello World!";
  console.log(msg); 
}() // added () parentheses after body
//OUTPUT
Uncaught SyntaxError:Unexpected token

In the example above, we added a function name hello (line 2) but still it throws syntax error because it is not a valid syntax. This is because an self-executing function should be an function expression NOT function declaration and needs to be converted into an function expression.

Step Three: A function declaration can be converted into an function by wrapping the entire function inside a pair of parentheses, as shown below:

//create & define an anonymous function
(function() {
  let msg = "Hello World!";
  console.log(msg); 
})(); 
//OUTPUT - immediately created
Hello World!

In the example above, with the parentheses, the entire function is treated as an expression and its executed immediately.

An IIFE can be written in the following TWO ways:

//parentheses around function only
(function() {
  let msg = "Hello World!";
  console.log(msg); 
})(); //OUTPUT => Hello World!

//parentheses around the entire body
(function() {
  let msg = "Hello World!";
  console.log(msg); 
}()); //OUTPUT => Hello World!

The parentheses can be just around function body only (lines: 2-5) or the entire body (lines: 8-11).

While writing a IIFE following key points to remember:

  • A semicolon ; is required at the end of the IIFE body to convert the function defination into function expression (as in statement).
  • If function is defined as function expression, then Grouping Operator parentheses () is not required (because it’s already an expression) to enclose function body required in anonymous function.
    //Create IIFE with function expression
    let hello = function () {
       console.log("Hello World!");
    }();
    //OUTPUT (immediate invocation)
    Hello World!
  • Just like in an function, arguments can be passed to an IIFE, as described in the following section.
IIFE with Arguments

The basic syntax of the IIFE with parameters is very similar, shown below:

//basic syntax
(function(param1, param2) {
    // code block 
})(arg1, arg2);

//declare IIFE function
(function(a, b) {
    return a + b;
})(10,20);
//OUTPUT (immediately)
30

In the example above, the function is defined with two parameters (line 7)and to call the function, pass the arguments in same order(line 9). The function is executed it immediately creates output (line 11).

When to Use IIEF?

One of the common use of IIFEs is run untraceable functions. IIFEs can be run without leaving evidence for their existence, because they are nameless anonymous functions and their variable remain private (not accessible from outside).

Tip: IIFEs can be run inside a model (data encapsulation) and then disappearing without any trace.

Lets look at below some use cases of IIFEs:

1. Data Encapsulation

One of the common use case of IIFEs is to encapsulate certain block of code from outside interference. Lets’ say  we are writing a small function that will be used as part of another application (JS framework or libraries etc). Some of the variables, code block or methods could be similar (and may have same name) could be accidentally overwritten or override functions and methods. The IIFEs allows to encapsulate your code inside thus protecting local variables as well as accidental override or pollution from existing application.

2. Closure & Private Data

The JS closures is an advanced powerful ES6 features. To quote from You Don’t Know JS: Scope & Closuresclosure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope“. Kirupa has a detailed discussion on use of IIFE in making some data private.

Tip: Additional information on Js closures is described in a separate post – Deep Diving Into JavaScript Closures.

3. Module Pattern

Use of modular pattern in IIFEs is described with a use case example by Kirupa in this post.

Note: Full understanding of IIFEs and its use in JS requires better understanding of closure function. This topic will be revisited after learning closure.

Wrapping Up

In this post we discussed about Immediately Invoked Function Expression (IIFE), its basic syntax, how anonymous function are converted into IIFEs and its uses. To make full use of IIFE requires understanding of JS Closure function and will be revisited after understanding ES6 features.

Related Post: Understanding Deeply JavaScript Closure Function

Useful Resources & Links

While preparing this post, I have referred the following references extensively. Visit original link for additional information.