Encapsulation in JavaScript: IIFE and Revealing Module Pattern

Kadir Yavuz
2 min readAug 11, 2021

--

Encapsulation is about packing the data with the functions that allow to operate on that data. It’s fundamental to the OOP (object-oriented programming) and used with object-oriented languages like Java or C# in order to hide or limit the access/ usage of your structured object so you can control the state of it.

Well, JavaScript is not an object-oriented language but we want to work around the good parts of OOP, so we can apply encapsulation to a structured instance with a commonly used practice with IIFE (immediately-invoked function expression) and revealing module pattern.

IIFE

An immediately-invoked function expression is basically a function within a lexical scope but you combine it with a function expression () so JavaScript engine directly interprets the function when it’s defined and inner statements are not accessible from outside.

(function(){var myStore = [“Apple”, "Banana", "Mango", "Orange"]})();console.log("myStore is", myStore); 
// returns error: ReferenceError: myStore is not defined

You can only access to its inner statement by assigning your IIFE’s return value to a variable:

const store = (function () {var myStore = [“Apple”, “Banana”, “Mango”, “Orange”];return myStore;})();console.log(“myStore is”, store);
//myStore is [ 'Apple', 'Banana', 'Mango', 'Orange' ]

Since we aim to apply an encapsulation concept, let’s just consider an improved version of this store sample with the basic functions that we may have in a real-life like sample.

Revealing Module Pattern

Modules are most commonly used design patterns in JavaScript. It provides loose-coupling in order to have a well-structured code. Since IIFE provides private scope statements, when we use it with this pattern, we’ll have a well-designed encapsulated objects.

You can see how I designed the code above with this pattern:

const store = (() => {
/**
* private members => only private to constructor function scope
*/

const _store = ["Apple", "Banana", "Mango", "Orange"];
const _print = (data) => {
console.log("Inventory: ", data.toString());
}
/**
* public members
*/

return {
getInventory: () => _print(_store),
}
})();
store.getInventory();Returns Inventory: Apple,Banana,Mango,Orange

Note: I also use arrow function expression

Let’s modify it more:

const store = (() => {
/**
* private members => only private to constructor function scope
*/

const _store = ["Apple", "Banana", "Mango", "Orange"];
const _print = (data) => {
console.log("Inventory: ", data.toString());
}
const _addOne = (item) => {
_store.push(item);
}
/**
* public members
*/

return {
getInventory: () => _print(_store),
addInventory: (item) => _addOne(item),
}
})();
store.addInventory("Cherry");
store.getInventory();
Returns Inventory: Apple,Banana,Mango,Orange,Cherry

… and check how store function is actually exposed:

console.log("Store: ", store);Returns
Store: {
getInventory: [Function: getInventory],
addInventory: [Function: addInventory]
}

RMP is enabling store IIFE to successfully encapsulate its private members or state and only allows public members to access or operate on state.

Thank your for reading!

--

--

Kadir Yavuz

Software Developer, MSc in Management of Information Systems