IIFE (Immediately Invoked Function Expression)
IIFE
An IIFE stands for Immediately Invoked Function Expression. IIFE is a design pattern as well as the JavaScript function that executes as soon as they are defined. IIFE are very useful in javascript as they don't pollute the global object. An IIFE is a simple way to isolate variables declarations, as it is a good way of protecting the scope of your function and the variables within it.
Creating an IIFE
(function() {
console.log("Welcome to Tutorials Logic!");
})();
An IIFE can also be defined with arrow functions like this:
(() => {
console.log("Welcome to Tutorials Logic!");
})();
An IIFE can also be defined using named regular functions (except arrow functions) like this:
(function myFunction() {
console.log("Welcome to Tutorials Logic!");
})();
IIFE with Parameters
You can pass arguments to an IIFE just like any regular function. This is useful when you need to inject values into the private scope.
// Passing arguments to IIFE
(function(name, version) {
console.log(`App: ${name}, Version: ${version}`);
})('TutorialsLogic', '2.0');
// IIFE with return value
const result = (function(a, b) {
return a * b;
})(6, 7);
console.log(result); // 42
// Passing global objects safely
(function($, window, document) {
// $ is guaranteed to be jQuery here
$(document).ready(function() {
console.log('DOM ready');
});
})(jQuery, window, document);
IIFE for Module Pattern
Before ES6 modules, the IIFE module pattern was the standard way to create encapsulated, reusable code with public and private members.
const Counter = (function() {
// Private variable - not accessible outside
let count = 0;
// Public API
return {
increment() { count++; },
decrement() { count--; },
getCount() { return count; },
reset() { count = 0; }
};
})();
Counter.increment();
Counter.increment();
Counter.increment();
console.log(Counter.getCount()); // 3
Counter.reset();
console.log(Counter.getCount()); // 0
// console.log(count); // ReferenceError: count is not defined
IIFE vs ES6 Alternatives
With ES6+, block scoping with let/const and native modules reduce the need for IIFEs, but they are still widely used in legacy code and bundlers.
// Old way - IIFE for scope isolation
(function() {
var temp = 'only inside IIFE';
})();
// console.log(temp); // ReferenceError
// Modern way - block scope with let/const
{
const temp = 'only inside block';
console.log(temp); // only inside block
}
// console.log(temp); // ReferenceError
// IIFE still useful for async top-level (before top-level await)
(async function() {
const data = await fetch('/api/data');
const json = await data.json();
console.log(json);
})();
- IIFE executes immediately after definition - no need to call it separately.
- Variables inside an IIFE are private and do not pollute the global scope.
- You can pass arguments to an IIFE and capture its return value.
- The Module Pattern using IIFE was the standard before ES6 modules.
- Arrow function IIFEs (() => {})() work the same but cannot be used as constructors.
- In modern JS, block scoping with let/const often replaces simple IIFEs, but IIFEs remain useful for async patterns.