JavaScript IIFE (Immediately Invoked Function Expression)

An IIFE is a function that runs as soon as it is defined. It is a design pattern that creates a private scope, avoiding pollution of the global namespace. IIFEs were essential before ES6 modules and block-scoped variables.

IIFE Syntax

An IIFE is created by wrapping a function expression in parentheses and then immediately invoking it with another pair of parentheses.

Basic IIFE Syntax
// Standard IIFE syntax
(function() {
  const message = 'Hello from IIFE!';
  console.log(message);
})();

// Alternative syntax (parentheses placement)
(function() {
  console.log('Alternative syntax');
}());

// IIFE with parameters
(function(name, age) {
  console.log(name + ' is ' + age + ' years old');
})('Alice', 30);

Syntax Variations

There are several valid syntax variations for IIFEs. All achieve the same result: immediately executing a function expression.

Different IIFE Patterns
// Using void
void function() {
  console.log('void IIFE');
}();

// Using unary operators
+function() {
  console.log('+ IIFE');
}();

!function() {
  console.log('! IIFE');
}();

// Named IIFE (name only accessible inside)
(function myIIFE() {
  console.log('Named IIFE');
})();

// IIFE with return value
const result = (function() {
  return 42;
})();
console.log('Result: ' + result);

Avoiding Global Scope Pollution

The primary purpose of IIFEs is to create a private scope. Variables declared inside an IIFE are not accessible from outside, preventing conflicts with other scripts.

Private Scope with IIFE
// Without IIFE: variables pollute global scope
// var counter = 0;  // Global!
// var helper = function() {};  // Global!

// With IIFE: variables stay private
const app = (function() {
  let counter = 0;  // Private
  const secret = 'hidden';  // Private

  function increment() {
    counter++;
    return counter;
  }

  // Only expose what you want
  return {
    next: increment
  };
})();

console.log(app.next());
console.log(app.next());
console.log(app.next());
console.log(typeof counter);  // undefined (private!)

The Module Pattern

The module pattern uses an IIFE to create a module with private variables and public methods. This was the standard pattern for creating modules before ES6.

Module Pattern
const Calculator = (function() {
  // Private state
  let history = [];

  // Private function
  function addToHistory(operation) {
    history.push(operation);
  }

  // Public API
  return {
    add: function(a, b) {
      const result = a + b;
      addToHistory(a + ' + ' + b + ' = ' + result);
      return result;
    },
    subtract: function(a, b) {
      const result = a - b;
      addToHistory(a + ' - ' + b + ' = ' + result);
      return result;
    },
    getHistory: function() {
      return history.slice();
    }
  };
})();

console.log(Calculator.add(5, 3));
console.log(Calculator.subtract(10, 4));
console.log('History: ' + Calculator.getHistory());

Async IIFE and Arrow IIFE

IIFEs can also be async (for top-level await patterns) or use arrow function syntax for shorter code.

Async and Arrow IIFEs
// Arrow function IIFE
const greeting = (() => {
  const name = 'World';
  return 'Hello, ' + name + '!';
})();
console.log(greeting);

// Arrow IIFE with parameter
((name) => {
  console.log('Arrow IIFE: Hi, ' + name);
})('Alice');

// Async IIFE (useful for top-level await in scripts)
(async function() {
  // Can use await here
  const data = await Promise.resolve('async data');
  console.log('Async IIFE: ' + data);
})();

// Async arrow IIFE
(async () => {
  const result = await Promise.resolve(42);
  console.log('Async arrow IIFE: ' + result);
})();
IIFE Use CaseModern Alternative
Private scopeES6 block scope (let/const)
Module patternES6 modules (import/export)
Avoid global pollutionES6 modules (module scope)
Top-level awaitTop-level await in modules
Configuration objectsStill useful
One-time initializationStill useful
📝 Note: While ES6 modules and block-scoped variables (let/const) have reduced the need for IIFEs, they are still useful in certain scenarios: one-time initialization code, configuration, and when you need an immediately-executed async function in a non-module context.
Exercise:
What does IIFE stand for?
Try it YourselfCtrl+Enter to run
Click Run to see the output here.