IIFE, immediately invoked function expression
An IIFE (Immediately Invoked Function Expression) is a function that is created and called immediately, without a separate call by name. Its classic job is to get a scope of its own and leave no extra global variables behind.
Theory
TL;DR
- An IIFE is a function expression that is invoked in the same place where it is declared.
- The first pair of parentheses turns the function into an expression, the second pair calls it.
- The body of an IIFE has its own scope, so the variables inside do not pollute the global object (
windoworglobal). - Typical uses: one-time initialisation, hidden temporary variables, returning a ready-made config.
- An async IIFE,
(async () => { ... })(), lets you useawaitwhere top-level await is not available. - Since ES6 modules arrived the need for IIFEs has dropped, because every module already has its own scope.
Quick example
(function () {
console.log('Ran immediately after the declaration');
})();How the syntax works
Note the two pairs of parentheses:
- The first one,
(function () { ... }), turns the function into a function expression. Without it the engine would read the line as a function declaration, and a declaration cannot be called in place. - The second one,
(), immediately invokes that expression.
An IIFE takes arguments just like a regular function:
(function (name) {
console.log(`Hi, ${name}!`);
})('Maria');Prints:
Hi, Maria!The same thing with an arrow function is shorter, and is also commonly called an IIFE:
(() => {
console.log('Arrow IIFE');
})();What an IIFE is for
1. An isolated scope. IIFEs are often used to avoid name clashes and to keep the global scope clean:
(function () {
const secret = 'This value lives only inside the function';
console.log(secret);
})();
console.log(secret); // ReferenceError: secret is not definedThe secret variable is available only inside the IIFE.
2. One-time initialisation. An IIFE is convenient when you want to compute something once at load time and expose only the result:
const config = (() => {
const apiKey = '12345';
const baseUrl = 'https://api.example.com';
return { apiKey, baseUrl };
})();
console.log(config.apiKey); // 12345An object is returned outwards, while the intermediate variables stay encapsulated.
3. Async code at the top level. An IIFE can be made async so you can use await where top-level await is not available (in a plain script, or in CommonJS, for example):
(async () => {
const data = await fetch('/api/data').then((res) => res.json());
console.log(data);
})();IIFEs and modern modules
Before ES6 modules an IIFE was the main tool for encapsulating and structuring code: the "module pattern" was built on it. Today every file with import or export already has its own scope, so IIFEs are used less often. They are still useful for:
- one-time initialisation,
- isolating temporary variables inside a large function or script,
- running async code immediately.
In short:
| Property | Description |
|---|---|
| Name | IIFE, Immediately Invoked Function Expression |
| Idea | The function is created and called right away |
| Why | Isolation, initialisation, temporary variables |
| Notes | Does not pollute the global scope, can be async |
Common mistakes
- Forgetting the outer parentheses:
function () {}()in declaration position is a syntax error. - Omitting the semicolon at the end of the previous line: a line that starts with
(gets glued to the previous expression and is read as a call. - Expecting
varinside an IIFE to become global: it stays local, and that is exactly the point of an IIFE. - Thinking that an async IIFE blocks execution: it returns a promise, the code after it keeps running, so errors must be caught with
.catch()or withtry/catchinside. - Writing an IIFE in code that is already an ES6 module, where a separate scope is not needed.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.