Skip to content
Advertisement

How are IIFEs useful post ES6?

I’m learning JavaScript and I understand the general function types, closures, etc. But with IIFEs my initial reaction was “if its immediately invoked, why not just inline it”. So I went and read this article that describes “4 Practical Use Cases” for IIFEs. However, two of which are related to circumventing the scoping issues that come with vars (which are no longer a concern post ES6 with let and const being introduced). A third one deals with global variable naming conflicts (what namespaces generally deal with in C++). And, from what I can tell, Import Aliasing (which was also introduced in ES6) solves this problem.

The remaining use case is regarding closures:

The author claims that combining a closure with an IIFE provides us with “two great benefits”: 1) the scopes of variables is secured, and 2) you can modify variables inside a function from the outside. However, from my understanding of closures, you can have both those benefits with just a regular closure.

For instance,

const IIFEclosure = (() => {
  let v = 10;
  return {
    value: _ => v,
    set: newValue => v = newValue,
  };
})();

const handle = () => {
  let v = 10;
  return {
    value: _ => v,
    set: newValue => v = newValue,
  };
};
const closure1 = handle();
const closure2 = handle();

console.log(IIFEclosure.value(), closure1.value(), closure2.value()) // 10 10 10
IIFEclosure.set(20);
closure1.set(30);
closure2.set(40);
console.log(IIFEclosure.value(), closure1.value(), closure2.value()) // 20 30 40

The only difference I can see here is that you can create multiple instances of the regular closure using handle while with IIFEclosure there can be only one since its immediately invoked in place and has no “handle”. I guess it has the upside of not polluting the namespace with an extra variable name. I am not sure if in practice having a closure that can only be instantiated once is useful or not. But, other than that, as far as I can tell, both benefits mentioned above are satisfied in both examples.

So if my above reasoning is valid, this leads me to opening question; what, if any, are the benefits/usecases of IIFEs in post ES6 JavaScript?

Advertisement

Answer

For closures there is still a small advantage: the function itself can be anonymous, avoiding one (function) variable. For instance, in your example, the non-IIFE has the handle as extra variable. If you want to minimise the littering of the current scope (maybe even the global scope) then IIFEs are still useful.

I also find IIFE useful at the top level for using await — although that would be named an IIAFE:

(async () => {
    const response = await fetch("....");
    const object = await response.json();
    // ...
    const result = await lookup(object.id);
    // ...
})();

Since ECMAScript 2022 introduced top-level await, it is no longer needed to have such async wrappers in modules.

As to the use case of global name aliasing, that one can also be solved with a plain block:

{
    const $ = jQuery;
    // Here comes $-referencing code that will not conflict with "outside" $ use.
}
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement