Self-executing functions in JavaScript

Reading Time: 3 minutes 🕑

Last updated: March 21, 2022.

Self-executing functions in JavaScript are functions that are executed as soon as they are encountered upon running a script. They are formally known as immediately invoked function expressions (IIFEs).

Below is the syntax for a self-executing function. It consists of a normal function wrapped in parentheses, which is then executed by appending an empty pair of parentheses:

/*** Sytnax of an immediately invoked function expressions (IIFE) ***/

(function myIIFE () { // named
    // Code to execute
  })();

(function () { // anonymous
    // Code to execute
  })();

An IIFE can be either named (e.g. above myIIFE) or anonymous. Either way, it can only be called once. But naming is better for debugging.

You can also write a self-executing function with arrow syntax, in which case it is always anonymous:

/*** IIFE defined with an arrow function ***/

(() => {
    // Code to execute
 })();

You can also write a self-executing asynchronous function, which enables the use of the keyword await:

 /*** An async IIFE ***/

(async function myAsyncIIFE () {
    // Code to execute (for use with 'await' keyword)
 })()

What purpose is served by self-executing functions?

The main reason to use a self-executing function is to execute some one-time code that will not interfere in any way with the rest of a code base.

There is no interference because the code inside a self-executing function (including the function itself) is contained within function scope. This means that the function and variable names inside an IIFE do not clash with anything defined outside it.

The ideal use case for a self-executing function is running a one-time process upon page loading.

For example, the following code snippet dynamically loads a banner image. If you try to access the loadBanner function or the myImage variable by name outside the IIFE, it returns 'not defined'.

/*** IIFEs do not 'pollute' the global scope ***/

(function loadBanner() {
   const img = document.createElement('img');
    img.src = "https://unsplash.it/600/100";
    document.body.prepend(img);
 })();

 console.log(loadBanner); // loadBanner is not defined
 console.log(img); // myImage is not defined

So the nice thing about an IIFE is generic names can be used (e.g. img, loadBanner) without worrying about naming conflicts. This applies to both variables and the name of the function.

Self-executing function v. calling a function once

You might be wondering: why not just define a loadBanner function in the normal way and then call it?

For example:

/*** IIFE alternative: define a function and call it once ***/

function loadBanner () {
   const img = document.createElement('img');
    img.src = "https://unsplash.it/600/100";
    document.body.prepend(img);
 }

loadBanner() 

This solution produces the same result. But there are two reasons why a self-executing function would be more appropriate.

The first is semantic: when you encounter a self-executing function in the global scope, you can be sure that the code contained within it is meant to be executed only once, without the need for any commenting. If it is a regular function, you cannot be sure: perhaps it will also be called somewhere else later in the code.

The second reason is technical: the contents of a self-executing function are better contained from interfering with the rest of a code base. Specifically, if the function nested within an IIFE is named, it only exists within the scope of the IIFE.

/*** IIFE function names are not saved in global scope ***/

(function myIIFE () {
   const img = document.createElement('img');
    img.src = "https://unsplash.it/600/100";
    document.body.prepend(img);
 })();

function myIIFE() {
   console.log("I do another task");
}

myIIFE() // Returns "I do another task" (no clash between IIFE and function)

Name clashes may seem unlikely, but the risk increases when working on larger code bases.

And if the function will only run once, why take the risk? An IIFE guarantees no name clash.

Anonymous v. named nested function

You cannot call the function nested within an IIFE within the global scope. But you should still name it.

The reason is that even though you cannot reference it elsewhere in your code, the name of the function will be referenced by the debugger if something goes wrong inside the nested function.

For a non-named function, the error will occur inside 'anonymous'. For a named function, the name of the function in which the error has occurred will be provided in the console output.

Thus, even though it won't improve functionality, it is good practice to name the nested function.

Summary

In summary, you should use a self-executing function in JavaScript when you want to:

  • Run code as soon as it is encountered
  • Contain a process within function scope
  • Semantically signal to the reader of the script that the function runs only once
  • Prevent a function name being saved in global scope

Related links