Immediately Invoked Function Expressions in JavaScript

Immediately Invoked Function Expressions in JavaScript

This article is also available in other languages.

An IIFE (Immediately Invoked Function Expression) is, as the name says, a function that runs as soon as it is declared.

If you create a function and want to run it right away, you would normally write something like this.

function a() {
  console.log('hello world');
}
a();

If the function only ever needs to be called once, spending a variable named a on it feels wasteful. The IIFE pattern lets you shorten this.

(function () {
  console.log('hello world');
})();

Because an IIFE runs as soon as it is declared, it does not need a name (it is a function expression) and no error is thrown. Its return value becomes the value assigned to the variable.

var a = (function () {
  return 3;
})();
console.log(a); // 3;

An IIFE also lets you achieve variable encapsulation in JavaScript.

/* b is not guaranteed to stay unchanged. */
var a = {
  b: 3;
};
a.b = 5;

/* b is guaranteed to stay unchanged. */
var a = (function () {
  // b cannot be changed from the outside.
  var b = 3;
	return {
    getB() {
      return b;
    }
  };
})();

console.log(a.getB()); // 3;
console.log(a.b); // undefined;

That is why most browser libraries are wrapped in seemingly meaningless code like (() ⇒ {})(): they rely on this encapsulation.

An IIFE can also improve performance. Look at the following code.

function getSomeValue(a, b) {
	function squared(num) {
    return num * num;
  }
  function subtractOne(num) {
    return num - 1;
  }
  return squared(a) + subtractOne(b);
}

console.time('task');
Array.from(new Array(10000000)).forEach(() => {
  getSomeValue(5, 5);
});
console.timeEnd('task');
// 350ms;

Running this takes about 350ms (on my machine). The problem is that the code redefines the squared and subtractOne functions every time getSomeValue is called.

You could move squared and subtractOne out to the global scope, but that is risky because other code could then reference or modify them.

An IIFE is useful here as well.

var getSomeValue = (function () {
  /* This function is assigned only once and cannot be changed from the outside. */
	function squared(num) {
    return num * num;
  }
  /* This function is assigned only once and cannot be changed from the outside. */
  function subtractOne(num) {
    return num - 1;
  }
  /* Only this part is actually called. */
  return function (a, b) {
    return squared(a) + subtractOne(b);
  }
})();

console.time('task');
Array.from(new Array(10000000)).forEach(() => {
  getSomeValue(5, 5);
});
console.timeEnd('task');
// 200ms;

JavaScript originally had no classes. The class syntax is just syntactic sugar. As proof, printing the type of a class gives you this.

class A {};
console.log(typeof A); // function

Under the hood, JavaScript classes are implemented with functions, and IIFEs are used as well. A simple class looks like this.

var Person = (function () {

  function Constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  Constructor.prototype.getName = function () {
    return this.name;
  }

  Constructor.prototype.getAge = function () {
    return this.age;
  }

  return Constructor;
})();

var person = new Person('winetree94', 20);

console.log(person.getName());
console.log(person.getAge());

References

author profile
winetree94

Web frontend engineer. Bedroom DevOps engineer.
I'd love to blog consistently, but let's be real—I'm way too lazy for that.