IIFE... Excuse me, what?

guennithegun

guennithegun

Posted on December 7, 2019

IIFE... Excuse me, what?

Since the first time I read about IIFE, I could not forget this abbreviation. Iffy...

IIFE stands for immediately invoked function expression. It is a JavaScript function that runs as soon as it is defined. It is a design pattern which is also known as a self executing anonymous function.

The syntax looks like this:

  // IIFE
  (function(){
    // do something here
  })();

So what do we have here? Let's go into details. The IIFE contains two major parts.

anonymous function

The first part is the anonymous function with lexical scope:

  // I am anonymous
  function(){
    // do something here
  };

Hold on a minute what is lexical scope? Check this article for some details on that topic: I would try to explain lexical scope in plain English. Wish me luck.

An anonymous function is a function that was declared without any named identifier to refer to it. It is usually not accessible after its initial creation.

  // normal function definition
  function hello() {
    console.log('A is A');
  };

  hello(); // output 'A is A'

  // anonymous function definition
  function(){
    // do something
  });

A common use for anonymous functions is for example as argument to another function.

  // example
  setTimeout(function() {
    alert('I am John Galt.');
  }, 1000);

In the IIFE the anonymous function is enclosed within the grouping operator ().

direct interpretation of the function

The second part creates the immediately invoked function expression () through which the JavaScript engine will directly interpret the function. The difference to the normal function definition is that with IIFE, declaration and execution are performed at the same time. With the normal function definition you first declare the function and then call it, placing the parentheses after it to indicate that you want to execute it.

why use IIFE?

Ok, so now we know a bit more about the syntax. But what is the benefit of IIFE?

It is about scope. In JavaScript variables declared outside of a function are global variables. Functions declared inside of a function are called local variables.

A global variable can be accessed from anywhere in your code. This comes with some downsides like

  • you can (accidentally) access the global state, which leads to impure functions
  • you can overwrite other global variables

Imagine you have two JavaScript files and each contains var johnGalt = {}; The variable johnGalt would be global and therefore shared in all code and executed no matter in which file it was written.

To prevent this the IIFE pattern exists. When you wrap all your global variables into IIFE you take them their globalness. You can treat them as local variables within the IIFE as they are wrapped into a function. The variables within the expression can not be accessed from outside.

  (function() {
    var johnGalt = 'Who is';
  })();

  // variable can not be accessed
  console.log(johnGalt); // Uncaught ReferenceError: johnGalt is not defined

When you need access to the global variables inside the IIFE you can do something like this:

  var galtsGulch = (function() {
    var johnGalt = 'Who is';
    return johnGalt;
  })();

  console.log(galtsGulch); // output 'Who is'

If you assign the IIFE to a variable it does not store the function definition but its return value. So everything which is returned by the IIFE function is accessible from outside. This allows you to control what should be globally accessible and what should not.

You can also do some cool stuff and manipulate your global variables inside IIFE. You can do that like this:

  var galtsGulch = (function() {
    var residents = []; // empty array

    return {
      // add a resident
      add: function(resident) {
        residents.push(resident);
      },
      // get all residents
      getAll: function() {
        return residents;
      }
    };
  })();

  console.log(galtsGulch.getAll()); // []
  galtsGulch.add({ name: 'John Galt' });
  console.log(galtsGulch.getAll()); // [ Object { name: 'John Galt' } ]

Here the IIFE returns an object with the two keys add and getAll. So whenever you access galtsGulch it represents an object with these two keys. The two keys hold functions that allow you to interact with the residents variable from outside. add adds a resident to the array and getAll gets the complete 'residents' variable.

COOL!

conclusion

With the IIFE pattern it is nearly impossible to accidentally modify or access the shared state. That’s why this pattern is so useful, why it’s commonly used in many applications, and why you should use it, too!

💖 💪 🙅 🚩
guennithegun
guennithegun

Posted on December 7, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

What was your win this week?
weeklyretro What was your win this week?

November 29, 2024

Where GitOps Meets ClickOps
devops Where GitOps Meets ClickOps

November 29, 2024

How to Use KitOps with MLflow
beginners How to Use KitOps with MLflow

November 29, 2024