DEV Community

Chukwuma Anyadike
Chukwuma Anyadike

Posted on

IIFE Use Cases: Immediately Invoked Function Expressions In Action

Immediately invoked function expressions (IIFE), which are also known as self invoked functions, are blocks of code which are defined and executed immediately after creation. The function inside can use the function keyword (traditional way) or be an arrow function. Either way, the entire function is surrounded by a set of parentheses followed by another pair of parentheses. This second pair of parentheses is the invocation operator which allows the function to be immediately executed.

Traditional syntax with function declaration

(
    function () {
        console.log('IIFE called')
    }
)();
Enter fullscreen mode Exit fullscreen mode

Arrow function syntax

(
    () => console.log('IIFE with arrow function called')
)();
Enter fullscreen mode Exit fullscreen mode

Now that we know what an IIFE is, the next question is why is it useful? Here are some use cases.

  • Avoid polluting the global namespace by creating a new scope
  • To create closures with private variables
  • It is used to execute async and await functions
  • Creation of modules

As a matter of fact a significant part of my day job is performing automation testing using Puppeteer. These Puppeteer scripts are giant IIFEs (typically a few thousand lines long) which run code which tests the user interface (UI) of our applications. Anyway, let us continue to discuss our use cases.

Avoid pollution of the global namespace

What does this mean? Essentially it means avoiding name collision between global and local variables of the same name. This becomes more apparent in large enterprise applications where the possibility of reusing variable names increases, especially with multiple developers working on the same application. The example below illustrates this point.

//Global scope
const value = "This variable is in global scope and is called 'value'.";
const stateLocation = () => console.log("Now in global scope");

stateLocation();
console.log(value);
console.log("*********************************************************");

(
    function () {
        //Function scope
        const value = "This variable is in function scope and avoids global pollution even though the variable name 'value' is reused";
        const stateLocation = () => console.log("Now in function scope of IIFE");

        stateLocation();
        console.log(value);
    }
)();
Enter fullscreen mode Exit fullscreen mode

Once this code is executed the output is as follows:

Now in global scope
This variable is in global scope and is called 'value'.
*********************************************************
Now in function scope of IIFE
This variable is in function scope and avoids global pollution even though the variable name 'value' is reused
Enter fullscreen mode Exit fullscreen mode

To create closures with private variables

Recall that a closure is an inner function that has access to variables in the outer function scope. This example of an IIFE which calculates the area of a circle illustrates this point. Furthermore, the variable in the outer function is private because it is inaccessible outside of the function.

const areaOfCircle = (
    function () {
        const pi = Math.PI //private variable
        return function (radius) { //closure with access to outer scope private variable
            return pi * (radius ** 2)
        }
    }
)();

const areaWithRadius2 = areaOfCircle(10);
console.log('Area of a circle with a radius of 10 is ', areaWithRadius2);
// console.log('PI = ', pi); //ReferenceError: pi is not defined
Enter fullscreen mode Exit fullscreen mode

Output:

Area of a circle with a radius of 10 is  314.1592653589793
Enter fullscreen mode Exit fullscreen mode

Use to execute the async and await function

IIFEs are also useful for executing asynchronous operations such as network calls. The following example fetches a list of todos from an mock server.

(
    async function () {
        const response = await fetch('https://dummyjson.com/todos');
        const todosObject = await response.json();
        const todoList = todosObject.todos.map(todo => todo.todo);
        console.log(todoList);
    }
)();
Enter fullscreen mode Exit fullscreen mode

Creation of modules

Here is a module which performs operations using basic physics equations. It can be exported and used by other programs. I will discuss this further in another article Building a Command Line Physics Calculations Application with an IIFE Module Pattern. Note the use of private variables and closures.

export const physicsCalculations = (
    function () {

        //the below constants are private variables
        const g = 9.80665; //gravity constant in meters/second squared
        const c = 299792458; //speed of light in m/s

        //functions to be returned as methods in this module
        const velocity = (distance, time) => distance / time;
        const acceleration = (speed, time) => speed / time;
        const potentialEnergy = (mass, height) => mass * g * height;
        const momentum = (mass, speed) => mass * speed;
        const energy = (mass) => mass * (c ** 2);
        const force = (mass, acc) => mass * acc;
        const kineticEnergy = (mass, speed) => 0.5 * mass * (speed ** 2);

        //object containing named methods including two getter methods
        return {
            velocity,
            acceleration,
            potentialEnergy,
            momentum,
            energy,
            force,
            kineticEnergy,
            getSpeedOfLight: () => c,
            getGravityConstant: () => g
        }
    }
)();
Enter fullscreen mode Exit fullscreen mode

As one can see there are a myriad of use cases for IIFEs. It can make data more secure by encapsulating of data as well as adding modularity to applications.

Top comments (0)