What are Javascript's IIFE?

Damien Cosset - May 16 '20 - - Dev Community

Another acronym?

We loooove acronym don't we? KISS, DRY, TDD, LOL... So many concepts behind them, so much to remember. So, what's an IIFE in Javascript?

IIFE stands for Immediately Invoked Function Expression. You create a anonymous function and immediately call it, you know, with the parenthesis.

Below is a beautiful function expression, dated to about 4000BC. Author: Anonymous
A anonymous function

Here, we store a anonymous function in a variable. Later, we call that function by adding those parenthesis.

const myFunction = function () {
  console.log("A function has no name.");
};

//Calling the function
myFunction();
// A function has no name

An IIFE combines the anonymous function and the call step.

(function () {
  console.log("This is IIFE.");
})();

What is happening here? 3 things:

  • We have an anonymous function. That includes the function keyword, the parenthesis, the curly braces and the console.log statement. This is a function declaration
  • That function declaration is surrounded by parenthesis. This is what turns a function declaration into a function expression. Who knew two little parenthesis could have so much power?
  • Finally, the final parenthesis are calling that function expression, running the body of that function.

Congratulations, you just understood what an IIFE is made of! Which now begs the question, why the hell would I want to use one of those things anyway?

The why behind IIFE

The main reason why you would want to use an IIFE is to not pollute the global scope, and keep the content of your choosing inside your function private.

Because of the surrounding parenthesis, the IIFE has its own scope, which can not be accessed from the outside. Whatever you return from an IIFE will be the only things you can access from outside that IIFE.

(function () {
  let sayMyName = "Damien";
})();

console.log(iife.sayMyName); // sayMyName is not defined

If I want to make those variables accessible, I need to return it from that IIFE:

const iife = (function () {
  let sayMyName = "Damien";
  let privateVariable = "No trespassing!";

  let greeting = function () {
    console.log("Hello from the IIFE");
  };

  return {
    sayMyName,
    greeting,
  };
})();

console.log(iife.sayMyName); // Damien
iife.greeting(); // Hello from the IIFE
console.log(iife.privateVariable); // privateVariable is not defined

The plugins way

IIFE are quite popular when writing Javascript plugins. That allow the users to use the functionality several plugins without having their global scope invaded by thousands of variables. IIFEs just populate the global scope with what they need to work, usually just one variable.

You can find an example in a this article, where I wrote a simple Calendar plugin.

Basically, a plugin could look something like this. It's a bit more complicated, but it's still an IIFE.

(function (globalScope, whatWePopulateTheGlobalScopeWith) {
  globalScope.myCoolPlugin = whatWePopulateTheGlobalScopeWith();
})(this, function () {
  let launchThePlugin = () => {
    document.title = "PLUGIN LAUNCHED";
  };
  return {
    launchThePlugin,
  };
});

A bit more technical, let's break it down.

Notice that we still have the IIFE skeleton. A function declaration, surrounded by parenthesis, and immediately called. What might be throwing you off is that when we call the function expression, we give it parameters. The first parameter is this, which is the global scope.

In my case, the global scope in the window object, because my plugin runs in a browser. But it could be anything. The second parameter is a function.

In the main body of the IIFE, we populate the globalScope with whatever that function provided in the second parameter will return. Here, I'm returning a function called launchThePlugin. Which means, once this IIFE is executed, window.myCoolPlugin will equal the object that function returned.

The main body of the IIFE will populate the global scope, the other function will manage the plugin's functionalities. So, when I import my Javascript file in my HTML, I can run myCoolPlugin.launchThePlugin() (or window.myCoolPlugin.launchThePlugin()). This function will update the document's title.

I can add a whole bunch of things in that function, but as long as I do not return it, it will not be accessible from outside this function.

And that is the power, usefulness, awesomeness of IIFEs.

Hope it was clear! If not, let me know! ❤️

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .