Immediately Invoked Function Expression or IFFE (pronounced as ‘iffy’), as the name suggests, is a function expression which is ‘immediately invoked’. i.e. it is a function that gets executed as soon as it is defined.
However, before diving deep into the ‘what’ and ‘why’ of IIFE, let’s step back a little and look into some of the concepts of ‘functions’ in JavaScript, which will help us understand IIFE more in-depth.
In JavaScript, a ‘function’ is a block of code. It is designed to perform a particular task. To execute a function, we have to call the function, which is also known as invoking a function.
There are two ways we can define a ‘function’ in JavaScript.
1. Function Declaration: Function Declarations begin with the ‘function’ keyword, followed by the function name. To execute the function, we have to call or invoke it. We can do that by adding ‘()’ at the end of the function name. Here’s an example to make things clear.
Example:
// Function Declaration function greeting() { return "Hello Everyone!"; } greeting( ); //Invoking the function to execute it
2. Function Expression: Function Expressions are first created and then stored in a variable. These, unlike Function Declarations, do not start with the ‘function’ keyword. Function expressions can be anonymous, named or an IIFE.
Examples:
// Anonymous function expressions (starts with ’var’) var greeting = function() { return “Hello Everyone!”; } greeting(); //Invoking the function to execute it Output: //Hello Everyone! // Named function expressions (starts with ’var’) var greeting = function hello() { return “Hello Everyone!”; } greeting(); //Invoking the function to execute it Output: //Hello Everyone! // Immediately Invoked function expressions ( starts with ’(’ ) (function() { console.log(“Hello Everyone!”); })(); Output: //Hello Everyone!
Now, that we are finally in the IIFE zone, let’s explore it further.
Creating an IIFE
To create an IIFE we have to wrap the function definition within parenthesis:
(function(){ console.log(“Not an IIFE yet! You didn't invoke me”); })
The opening parenthesis ‘(’ at the beginning of the function tells the JavaScript compiler that it is a function expression and not a function declaration as the function is not starting with a ‘function’ keyword.
To invoke the function immediately (well, that is the whole point of creating an IIFE) we just have to add ‘()’ at the end of the closing outer parenthesis.
(function() { console.log(“Yay! I am an IIFE!”); })(); Output: //Yay! I am an IIFE!
There we have it, a working IIFE.
Note: We can store an IIFE in a variable too, just like the named and anonymous function expressions. When we do so with an IIFE, the return value from the IIFE gets stored in the variable and not the function itself. As IIFE’s can be invoked only once, we cannot use the variable name to invoke the IIFE again.
Example:
var result = (function() { var greeting = 'Hello Everyone!'; return greeting; })(); console.log(result); // Hello Everyone! (Output shows the return value) console.log(result()); // TypeError: result is not a function (Not able to invoke the IIFE again with the variable name)
IIFE Variations
There are two different ways to create an IIFE and both the variations are equally popular and generate the same result. We can use either of the variations as per our liking.
// Variation 1 (function() { console.log(“Hello from IIFE 1”); })(); Output: // Hello from IIFE 1 //Variation 2 (function() { console.log(“Hello from IIFE 2”); }()); Output: // Hello from IIFE 2
The difference between the two variations is rather minimal as you might have already noticed. In variation 1, the parenthesis for invoking the function is outside the closing wrapping parenthesis, whereas in variation 2, the parenthesis for invoking the function is inside the closing wrapping parenthesis as shown in the above example.
But Why Do We Need an IIFE?
Now that we know the ‘what’ of IIFE, let’s understand the ‘why’.
Data privacy is the main reason behind creation of IIFEs. Lets try to understand this concept using the example below:
Example:
(function hello() { // Private variables that no one has access to outside this IIFE var greeting; welcome(); // Private function that no one has access to outside this IIFE function welcome() { greeting = "Hello Everyone!" console.log(greeting); // Hello Everyone! } }()); console.log(greeting); // ReferenceError: greeting is not defined welcome(); // ReferenceError: welcome is not defined hello(); //ReferenceError: hello is not defined (Cannot invoke a named IIFE again)
In JavaScript, variables declared within a function have function scope. As a result they become inaccessible to the outside world. In the above example, the variable ‘greeting’ and function ‘welcome’ are contained within the IIFE, therefore we can only access them inside the function. When we try to access them outside the function we get a reference error.
Wait, but we could achieve the same result by creating a named function declaration and invoking it immediately, isn’t it? Yes we could, but there are couple of other advantages to IIFE which are not available to a named function declaration.
IIFE can either be a named function or an anonymous one, as we saw in our last example (which is a named IIFE called ‘hello’). Either way, it has the advantage of eliminating the possibility of a global name collision as the names defined within an IIFE do not ‘leak’ to the global namespace. Secondly, it prevents the function from getting invoked accidentally as IIFE’s can be invoked only once.
So, that’s all about IIFE. Now it’s time to start using it in code and experience the magic that happens with it.
Thanks for reading!