DEV Community

loading...
Cover image for Javascript pattern that changed everything (for me...)

Javascript pattern that changed everything (for me...)

kristijanfistrek profile image KristijanFištrek ・5 min read

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 :

  1. 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.
  2. 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.

  1. https://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript
  2. https://gist.github.com/zcaceres/bb0eec99c02dda6aac0e041d0d4d7bf2
  3. 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 &copy; 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.

Discussion (16)

pic
Editor guide
Collapse
stereobooster profile image
stereobooster

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:

  • modules, which has local scoping
  • let and const which has lexical scoping
  • arrow functions which automatically bind this to parent scope

I haven't seen a lot of usage of IIFE in ES6.

Collapse
kristijanfistrek profile image
KristijanFištrek Author • Edited

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 ^

Collapse
hakuz profile image
Hakuz

Good Read..and what about writting the same article ...with ES6

Thread Thread
kristijanfistrek profile image
KristijanFištrek Author

Well, I guess I found my inspiration for the next post 😁 good idea!

Collapse
drewtownchi profile image
Drew Town

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.

const { start, increment, count } = myRevelaingModule;

Cheers and thanks for the article.

Collapse
kristijanfistrek profile image
KristijanFištrek Author

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 ^

Collapse
adam_cyclones profile image
Adam Crockett • Edited

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.

Collapse
kristijanfistrek profile image
KristijanFištrek Author

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 🙈

Collapse
adam_cyclones profile image
Collapse
chirag97 profile image
Chirag Chaudhari

awesome article... thanks for enlighting! Enjoy

Collapse
kristijanfistrek profile image
KristijanFištrek Author

No problem, thanks for commenting! 🤘

Collapse
fcfn profile image
Peter Timoshevsky

Thank G-d for ES6 and Babel!

Collapse
kristijanfistrek profile image
KristijanFištrek Author

IIFE ain't that bad 😄 but yeah, ES6 and Babel is marvelous!

Collapse
juancarlospaco profile image
Juan Carlos

is Anon Function even a design pattern?. 🤔

Collapse
kristijanfistrek profile image
KristijanFištrek Author

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 😄

Collapse
juancarlospaco profile image
Juan Carlos

Fair'nuff :)