All topics
Fundamentalsbeginner

Immediately Invoked Function Expressions Basics

A function that runs the instant it's defined, historically used to create private scope before block-scoping and modules existed.

An IIFE is a function that runs the moment it is defined.

An IIFE is like unwrapping a candy, eating it immediately, and throwing away the wrapper in one motion — nothing about that candy lingers around for anyone else to grab afterward, except whatever taste (return value or closure) you deliberately kept.

Key Concepts

1
    (function () {
      // private scope
    })();
2
    (() => {
      // arrow version
    })();
3
Why the parentheses. A statement starting with function is parsed as a declaration, which cannot be invoked in place. Wrapping it makes it an expression.
function
4
What it was for. Before let and modules, var was function-scoped and everything at the top level became a global. An IIFE was the only way to keep names private.
letvar
5
    var myLib = (function () {
      var privateCount = 0;              // not reachable outside
      return {
        increment: function () { return ++privateCount; }
      };
    })();
6
That is the module pattern, and it is what every library did before 2015.
7
The loop fix it used to provide.
    for (var i = 0; i < 3; i++) {
      (function (j) {
        setTimeout(() => console.log(j));
      })(i);
    }
    // 0 1 2
8
Each invocation captured its own j. let made this unnecessary — the same loop with let i behaves correctly on its own.
jletlet i
9
Which is why you see far fewer IIFEs in new code. Block scoping handles privacy inside a function, and ES modules handle it at file level: a module's top-level names are private unless exported.
10
Where they still appear.Top-level await before it was supported, and still in scripts that are not modules:
11
    (async () => {
      const data = await fetch(url);
    })();
12
Bundled output. Build tools wrap modules in IIFEs, so you meet them constantly in generated code.
13
Running something once at load, where naming the function adds nothing.
14
Recognising one matters more than writing one. It is a shape that appears throughout older code and in every bundle, and reading it is the skill — the reason it exists is a problem the language has since solved.
15
What the interviewer is probing.1. "What problem did the IIFE solve?" Probing: historical context. Stalls: "Nothing." *Moves up:* before block scope and modules it was the only way to create a private scope and avoid polluting the global namespace.
16
2. "Is it still needed?" Probing: currency. Stalls: "Yes, always use one." Moves up: rarely — block scoping with let and ES modules both give scope isolation, though an IIFE still helps for an immediate async context.
17
3. "Why do you need the wrapping parentheses?" Probing: parsing. Stalls: "Style." *Moves up:* a statement starting with function is parsed as a declaration, so the parentheses force it to be an expression.
18
4. "How does an async IIFE help?" Probing: the practical remaining use. Stalls: "It does not." Moves up: it gives you an await context in a script without top-level await.