Foreword
Hello there good people of Dev.to & welcome to my first Dev.to post!
I've been a member of this community for a while and finally decided to contribute & share my thoughts about a subject I'm passionate about.
I am still learning all the ways in which I can use the forthcoming pattern, so feel free to correct me down below if you see something stinky.
What will this post be about?
A short table of contents :
1) What is IIFE?
2) JS pattern that changed everything...
2.1) Advantages
2.2) Disadvantages
3) Examples
4) Closing words
Let's get into it!
1. IIFE
Before we head into explaining any sort of javascript design pattern, I think it's worth mentioning IIFE.
What is IIFE?
IIFE stands for immediately-invoked function expression or Self-Executing Anonymous Function.
In simple terms, it is a block of code that is invoked or called as soon as the file is executed.
And it looks something like this :
(function() {
})();
In not so simple terms, it is a way of encapsulating your functions within a scope that will keep it away from the global scope, which might be a tricky place in the javascript world.
It consists of primarily two parts :
- First part is an anonymous functions enclosed within a grouping operator () which limits the access to your data within the function and as we said before, keeps it away from the global scope.
- The second part creates the immediately executing function expression (); through which the JavaScript engine will directly interpret the function.
If you're curious about it and want to learn more, since I want to put emphasis on the javascript patterns here, you can read more on : https://developer.mozilla.org/en-US/docs/Glossary/IIFE?source=post_page---------------------------
2. Javascript pattern that changed everything
A pattern that changed everything, at least for me, is : drumroll
Revealing module pattern
Example:
var module = (function() {
function _setName() {
console.log("My name is : Slim Shady");
}
return {
init: _setName
};
})();
module.init();
You might see something familiar, and if your guess is IIFE, then you're completely correct.
Revealing module pattern, just like many other javascript patterns, takes advantage of IIFE to hide the functionalities of your code from the global scope, and enable you more consistency and re-usability.
All the properties you declare within the IIFE scope are inherently private, and you decide what you will expose to the outside in the return segment of our code.
Now let's break down our example from above.
1) We've declared an object by the name of module and we've saved in it a reference to whatever our IIFE function holds.
var module = (function() {
})();
2) The next step is to create our private function by the name of _setName() which in our case outputs a generic result.
I prefer to name my private properties with an underscore, it helps me to differentiate them from the rest and makes the debbuging easier.
var module = (function() {
function _setName() {
console.log("My name is : Slim Shady");
}
})();
3) The crucial segment of our example comes in a form a return statement, where we reveal the functionality of our private properties as public.
Since in this example we only have one private property, we shall have only one public property, although examples may vary depending on the complexity of your function.
var module = (function() {
function _setName() {
console.log("My name is : Slim Shady");
}
return {
init: _setName
}
})();
The final step is calling whatever we need through our module object.
By calling our module object we can access everything we've returned as public in our return scope.
Therefore if we type module.init() , in our console we will see the console log from the _setName() function.
That's because our init property stores whatever value _setName function might hold.
var module = (function() {
function _setName() {
console.log("My name is : Slim Shady");
}
return {
init: _setName
}
})();
module.init();
// Console log
// My name is : Slim Shady
For further information that expand beyond this simple example, check out the links below for in depth analysis of revealing module pattern.
- https://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript
- https://gist.github.com/zcaceres/bb0eec99c02dda6aac0e041d0d4d7bf2
- https://developerslogblog.wordpress.com/2017/11/05/javascript-quick-guide-to-the-revealing-module-pattern/
Advantages
The big advantage of this pattern is the fact that it allows the syntax of our scripts to be more consistent. It also makes it more clear at the end of the module which of our functions and variables may be accessed publicly which eases readability.
Disadvantages
An uncomfortable disadvantage of this pattern is that if a private function refers to a public function, that public function can't be overridden if a patch is necessary. This is because the private function will continue to refer to the private implementation and the pattern doesn't apply to public members, only to functions.
So care should be taken during the usage of this pattern, because modules created with the Revealing Module pattern may be more fragile than those created with the original Module pattern.
3. Examples
Here are some of the examples of module revealing pattern in use.
Some examples are the direct usage of MRT in some of my projects, and some of them are made up on the spot.
Hopefully you'll find them helpful!
Example #1 - The footer component
This piece of code displays a module revealing pattern that holds the structure of a footer, and basically creates a component which you can re-use throughout your website and save yourself a couple of lines of HTML code.
var footer = (function() {
var _footerDesign = function() {
var html = '';
html += '<div class="footer-content text-center">';
html += '<small><b>Copyright © Kristijan Fištrek</b></small>';
html += '</div>';
return html;
}
var render = function() {
var footerContainer = document.querySelector('footer');
footerContainer.innerHTML = _footerDesign();
}
return {
init: render
}
})();
footer.init();
Example #2 - Data storage
This examples portraits a way of defining a certain data set and keeping it structure private.
The only public aspect of it is the object that is returned.
var blogsContainer = (function() {
var blogs = [
{
id: 1,
name: 'Welcome to my first blog!',
description: 'Allow me to introduce myself & the content you can expect from me in my blogs. Primarily I will focus on delivering tech driven content, mostly about web development, but I have few ideas about project organization, agile methodology & much more!',
imgURL: 'assets/img/blogs/1.Welcome/1.Welcome-header.jpg',
destination: 'pages/blogs/welcome-blog.html'
}
]
var initialize = function() {
var contentOfBlogs = blogs;
return contentOfBlogs;
}
return {
data: initialize
}
})();
Example #3 - Addy Osmani example
var myRevealingModule = (function () {
var privateCounter = 0;
function privateFunction() {
privateCounter++;
}
function publicFunction() {
publicIncrement();
}
function publicIncrement() {
privateFunction();
}
function publicGetCount(){
return privateCounter;
}
// Reveal public pointers to
// private functions and properties
return {
start: publicFunction,
increment: publicIncrement,
count: publicGetCount
};
})();
myRevealingModule.start();
4. Closing words
I apologize for the long post, I really wanted to cover everything I considered important.
Since this is my first time writing anything on Dev.to, I believe a couple of mistakes have found their way into the content despite my relentless care.
Revealing module pattern is a powerful tool that should be used wisely, it is not perfect for every occasion, but it might prove itself useful in many others.
How did you like this lesson?
Do you think I covered enough?
What else would you like for me to cover?
Let's talk down below.
Cheers people, happy coding.
After reading this I realized that this is more or less the pattern the Vue function API proposal is using with some framework specific stuff sprinkled in. I didn't know that 😊
One thing that comes up in their examples is that you can use destructuring to get those methods/values out of the function to use them directly.
Cheers and thanks for the article.