A pair of parentheses at the end of the line, right after a function, and the body runs at once. The function has no name, nobody will ever call it again, and that is exactly the intent.
This form was long the only way to isolate variables in JavaScript. Modules have largely replaced it, but it is still around and keeps one very much alive use.
Definition
An IIFE, short for immediately invoked function expression, is a function defined and called within the same expression. The parentheses around it turn it into an expression, and the ones that follow run it.
(function () {
const secret = "invisible outside";
console.log(secret);
})();
// console.log(secret); // ReferenceError
const version = (function () {
return "1.4.0";
})();
console.log(version); // 1.4.0Everything declared inside stays locked in the function Scope. Nothing leaks out, except what the expression explicitly returns.
What it solved, and what replaced it
Before 2015, var was the only declaration keyword, and its scope stopped at the function. With no function, everything ended up global.
- Isolating variables: the job of let and const, which a plain pair of braces now covers.
- Creating a private module: the job of modules, where nothing leaves without an export.
- Avoiding name collisions: solved along the way, since every file has its own scope.
An IIFE written today for one of those three reasons is an inherited reflex, not a necessity.
The case that stays useful
Opening an asynchronous area inside a file that is not one. await requires an async function, and the IIFE supplies one without adding another name to the file.
(async () => {
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
await wait(10);
console.log("done after the wait");
})();In a module, top-level await makes even this form unnecessary. It remains essential in a classic script and in CommonJS files.
Frequently asked questions
Why does the function need surrounding parentheses?
Because a line starting with the function keyword is read as a declaration, and a declaration cannot be called. The parentheses force the parser to see an expression, which can then be invoked. An operator at the start of the line, such as an exclamation mark, has the same effect.
Can a Arrow function act as an IIFE?
Yes, and it is the shortest form today. An arrow is already an expression, so the wrapping parentheses only serve readability. One caveat though: it has no this of its own and no arguments object, which makes it unsuitable for some historical uses.
Should it be removed from older code?
Not systematically. An IIFE wrapping a whole file costs nothing at runtime, and converting it into a module means touching how the file is loaded as well. The replacement is worth it when you open the file for other reasons, not as a standalone project.