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.
Top comments (16)
In ES6 you need it less. IIFE was needed in ES5, because there were no lexical scoping (only scoping to function body), so if you needed some isolation you would use closures and IIFE everywhere.
ES6 introduces:
let
andconst
which has lexical scopingI haven't seen a lot of usage of IIFE in ES6.
I absolutely love ES6 because of that, it blew me away!
However, I've had slight compatibility issues with certain ES6 features and I was forced to use Babel or some other tricks to make it work across all browsers and devices :/
Plus, I've seen couple of developers killing it with ES6, but they weren't aware what's going on behind something like an arrow function or even how local and global scoping acts according to certain definitions, so even though I think this is almost old school and slightly obsolete :D I do think it's cool to know how it was done before and what's going on under the hood, so to speak.
But you're completely right. IIFE is not necessary in ES6 ^
Good Read..and what about writting the same article ...with ES6
Well, I guess I found my inspiration for the next post 😁 good idea!
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.
Didn't know that! 😮
Unfortunately I am out of Vue world, although I hear its amazing and I should jump aboard, but I do know that several jQuery plugins and certain Angular functionalities use this or similar techniques to ensure encapsulation of their data.🙃
I would definitely recommend Addy Osmani Javascript Design Patterns to everyone interested in this kind of stuff ^
The privacy really bothers me, to the point where I am not sure this pattern actually achieves it's goals. Exposed private methods are no longer private, in much the same way if I had no trousers my private would be public for all the world to see.
As far as I have learned, what is public is only the reference to what the private function holds. Therefore its internal state or value remains untouched from the outside, or so to speak you can not change what has been defined, you can only view or read what has been exposed. It's like having only the Read segment of CRUD, let's say.
In your analogy, it's like taking down the pants but there's a drawing of your private parts covering them 😄, you can still kind of see what they look like, but if someone were to touch it he would be touching a drawing and not a real thing.
I never thought I would enter a conversation where a correlation between man's private parts and JS pattern is drawn 🙈
🤣
awesome article... thanks for enlighting! Enjoy
No problem, thanks for commenting! 🤘
Thank G-d for ES6 and Babel!
IIFE ain't that bad 😄 but yeah, ES6 and Babel is marvelous!
is Anon Function even a design pattern?. 🤔
I believe it depends on the context of their use.
Because as far as I know, correct me if I am wrong, in this context we have an anonymous function in conjunction with object reference and scope manipulation, which creates a sort of a pattern we can follow in order to replicate this behaviour.
At least that's what I have picked up so far 😄
Fair'nuff :)