Encapsulation with IIFE: How JavaScript’s Self-Invoking Functions Keep Code Clean

Explore Code With Me
3 min readJan 13, 2025

--

An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.

It is typically used to create a new scope, avoiding polluting the global scope with variables.

The syntax of an IIFE looks like this:

(function() {
// code here runs immediately
})();

Alternatively, you can use an arrow function to create an IIFE:

(() => {
// code here runs immediately
})();

Key Points:

Self-Executing: The function is executed immediately after being defined.

Anonymous: The function does not have a name.

Encapsulation: It helps avoid variable conflicts by creating a local scope.

(function() {
var message = "Hello, World!";
console.log(message); // Output: Hello, World!
})();

// message is not accessible here
// console.log(message); // ReferenceError: message is not defined

Why use an IIFE?

Avoid Global Variables:

Helps in avoiding polluting the global scope with unnecessary variables.

(function() {
var privateVar = "I'm private";
console.log(privateVar); // Output: I'm private
})();
// privateVar is not accessible outside the function
console.log(privateVar); // ReferenceError: privateVar is not defined

Module Pattern:

IIFEs are often used in the module pattern to encapsulate code and expose only the required API.

Example of a Module Pattern using IIFE:

var counterModule = (function() {
let counter = 0; // private variable

return {
increment: function() {
counter++;
console.log(counter);
},
decrement: function() {
counter--;
console.log(counter);
}
};
})();

counterModule.increment(); // Output: 1
counterModule.increment(); // Output: 2
counterModule.decrement(); // Output: 1

Creating Private Variables: IIFEs are great for creating private variables that cannot be accessed from the outside. This helps with data encapsulation, ensuring that the internal state remains protected.

var createPerson = (function() {
var name = "John"; // Private variable

return {
getName: function() {
return name; // Accessor for the private variable
},
setName: function(newName) {
name = newName; // Mutator for the private variable
}
};
})();

console.log(createPerson.getName()); // Output: John
createPerson.setName("Jane");
console.log(createPerson.getName()); // Output: Jane

Code Isolation in Loops:IIFEs are useful when you want to isolate variables in loops (for example, in for or forEach loops), especially when you want to preserve the loop variable in asynchronous callbacks.

for (var i = 0; i < 3; i++) {
(function(i) {
setTimeout(function() {
console.log(i); // Output: 0, 1, 2
}, 1000);
})(i);
}

Variants of IIFE Syntax

IIFEs can be written in slightly different forms based on your preferences or needs.

  1. Basic Function Expression:
(function() {
console.log("Hello from IIFE!");
})();

2. Arrow Function IIFE:

With ES6, you can use arrow functions to define an IIFE:

(() => {
console.log("Hello from arrow function IIFE!");
})();

3. Named IIFE:

While less common, you can give the function a name within the IIFE. However, it’s still immediately invoked.

(function myFunction() {
console.log("Hello from named IIFE!");
})();

4. IIFE with Parameters:

You can pass arguments into an IIFE, just like with regular functions:

  (function(a, b) {
console.log(a + b); // Output: 5
})(2, 3);

5. IIFE with ES6 Modules:

With ES6 modules, the IIFE pattern is not as widely used anymore, but it was once a common method of achieving module-like behavior in JavaScript prior to the import/export syntax:

const myModule = (function() {
let privateVar = 0;

return {
increment: function() {
privateVar++;
return privateVar;
}
};
})();

console.log(myModule.increment()); // Output: 1

Conclusion

IIFEs are a powerful JavaScript pattern for:

  • Encapsulation and privacy
  • Avoiding global scope pollution
  • Creating modules
  • Managing scope in loops and asynchronous code

Even though the module pattern and ES6 features like let, const, and import/export have provided more modern alternatives, IIFEs remain an essential concept in JavaScript, especially for legacy code and understanding how scoping works in JavaScript.

--

--

Explore Code With Me
Explore Code With Me

Responses (3)