Do ES6 Modules make the case of IIFEs obsolete?

IIFEs are generally used as a design pattern for providing “privacy” to an extent through anonymous closures. Does the emergence of ES6 modules make the usage of IIFEs obsolete?

Or do you still have use cases for IIFEs? If yes, an example to drive your case would be awesome!

Write your answer…

IIFE was one of the most used patterns in the ES5 standard, as functions were the only way to declare a scoped block of code. So the following code will result with a ReferenceError:

(function() {
    var scoped = 42;
}());

console.log(scoped); // ReferenceError

ECMAScript introduced the block scoped let and const, so instead of using an IIFE, we can have the following code:

{
    let scoped = 42;
}

console.log(scoped); // ReferenceError

The later example is way more clear and understandable.

IIFEs were used as a building block in the revealing module pattern. Its advantage is that it clearly separates between what is public and what is private:

var myModule = (function() {
    // private variable, accessible only inside the IIFE
    var counter = 0;

    function increment() {
        counter++;
    }

    // publicly exposed logic
    return {    
        increment: increment
    }
}());

Instead of using this pattern, with ES6 we can use modules. Modules declare their own scope and variables created inside the module will not polute the global object:

// myModule.js

let counter = 0;

export function increment() {
    counter++;
}    

// logic.js

import {increment} from 'myModule.js';

increment();

The only case, where you may want to use an IIFE is with an immediately-invoked arrow functions. Sometimes you only can produce a result via a sequence of statements, not via a single expression and if you want to inline these statements, you have to immediately invoke a function:

const SENTENCE = 'Hello world, how are you?';
const REVERSE = (() => {
    const array  = [...SENTENCE];
    array.reverse();
    return arr.join('');
})();

Keep in mind, that you need to wrap the arrow function in parentheses (they doesn't wrap the whole function).

As a rule of thumb you want to avoid using IIFEs in ES6, as there are other way to handle global variable polution.

Kleo ePetrov can you explain that another way of handling the global variable pollution in ES6. Usually I used to wrap all my JS files with (function() {})(); IIFE, which will avoid polluting the global space.

Reply to this…

Hashnode is a friendly and inclusive dev community.
Come jump on the bandwagon!

  • 💬 Ask programming questions without being judged

  • 🧠 Stay in the loop and grow your knowledge

  • 🍕 More than 500K developers share programming wisdom here

  • ❤️ Support the growing dev community!

Create my profile

In sense of providing a private scope: YES, you don't need them.

ESM have their own scope and don't pollute the global scope.

Reply to this…