Facebook Pixel

Block Scope and the IIFE Pattern in JavaScript

Before let and const, IIFEs created block-like scope. Here is how they compare and when you still need an IIFE.

Block Scope and the IIFE Pattern in JavaScript

Before ES6, JavaScript did not have block scope (only function scope). Developers used IIFEs (Immediately Invoked Function Expressions) to create block-like scope. Here is how they compare to modern block scope.

The Old Problem

// pre-ES6, only var for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); } // logs 3, 3, 3 (all share one i) `` `var` is function-scoped, so all iterations share one `i`. ### The IIFE Fix ```js for (var i = 0; i < 3; i++) { (function (j) { setTimeout(() => console.log(j), 0); })(i); } // logs 0, 1, 2 `` The IIFE creates a new function scope per iteration, capturing `i` as `j`. Each callback closes over its own `j`. ### The Modern `let` Fix ```js for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); } // logs 0, 1, 2 `` `let` is block-scoped and creates a fresh binding per iteration. No IIFE needed. ### IIFE for Data Privacy Before `const` and modules, IIFEs were used to create private scope: ```js const counter = (function () { let count = 0; return { increment: () => ++count, getCount: () => count, }; })(); counter.increment(); counter.getCount(); // 1 `` Today, you can use a regular function: ```js function createCounter() { let count = 0; return { increment: () => ++count, getCount: () => count, }; } const counter = createCounter(); `` ### IIFE to Avoid Global Pollution Before modules, IIFEs wrapped entire files to avoid leaking `var` to the global scope: ```js (function () { var privateVar = "hidden"; // ... code ... })(); // privateVar is not accessible here `` Today, ES modules do this automatically. Top-level `let`/`const`/`var` in a module are module-scoped. ### When You Still Need an IIFE - In old codebases that do not support ES6 or modules. - To create a one-off scope in a non-module script without `let`/`const`. - To avoid `var` leaking to the global scope in a script tag. ### The Takeaway IIFEs were the pre-ES6 way to create block-like scope for data privacy and loop closure fixes. Modern `let`/`const` and ES modules make IIFEs mostly unnecessary. Use `let` in loops, regular functions for data privacy, and modules to avoid global pollution. IIFEs are still useful in old codebases.

An Immediately Invoked Function Expression. It creates a new function scope immediately. Before ES6, it was used to create block-like scope for data privacy, to avoid global pollution, and to fix the var loop closure bug.

let is block-scoped and creates a fresh binding per iteration. Each callback closes over its own i, fixing the var loop closure bug without needing an IIFE. The IIFE was the pre-ES6 workaround.

Rarely. let and const provide block scope, ES modules provide module scope (no global pollution), and regular functions provide data privacy. IIFEs are mainly needed in old codebases that do not support ES6 or modules.

By wrapping entire files in a function expression that ran immediately. var declarations inside the IIFE were scoped to the function, not the global object. Today, ES modules do this automatically.

By declaring variables inside the IIFE and returning an object with methods that access them. The variables are not accessible outside the IIFE, only through the returned methods. This is the module pattern.

Ready to master React completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.