Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

JavaScript Design Patterns

4.90/5 (21 votes)
3 Sep 2013CPOL3 min read 59.6K  
JavaScript has now emerged as the obvious language of client side web development. Right from start, browsers have introduced various features of support for accessing and modifying Document Object Model components. jQuery has abstracted most of native functionality into newer constructs and now pro

JavaScript has now emerged as the obvious language of client side web development. Right from start, browsers have introduced various features of support for accessing and modifying Document Object Model components. jQuery has abstracted most of native functionality into newer constructs and now progressive libraries like KnockOUT and BackBone are taking it a lot further.

However with native JavaScript there were certain issues, if not taken care of.

  • For variable declaration, if we forget "var", it becomes a global variable.
  • If two functions have same name in different JavaScript files, the one in the last file to be included in page, will remain and others are lost.
These can be ignored in smaller projects, but in huge applications with multiple developers working, they can create issues.
  • A variable without "var" will be in-scope of other JavaScript files also, mixing up variables in those. With lots of such variables spread across multiple files, it will be very difficult to locate the exact variable to be used for a purpose, often one variable will override all others and crash the whole state.
  • Functions for similar functionality having same name in different files (for different purpose) will clash. A code review can only identify issues within the same file, but if many such files are present, it creates an issue to find all same named functions.
Hence to solve such issues, certain design patterns have been introduced in JavaScript.

Simulated Classes

Change all global functions names and variables to tags and cover them under a single function scope. This creates a logical class; binding properties and functionalities together.

C#
// Class wrapping
var anchorChange = {
    config : {
            colors: ["#F12", "#999"]
    },

    alterColor:  function (link, newColor) {
        link.style.backgroundColor = newColor;
    },

    init : function() {
        var self = this;  // assign reference to current object to 'self'

        var anchors = document.getElementsByTagName("a");
        var size = anchors.length;

        for (var i = 0; i < size; i++) {
            anchors[i].color = self.config.colors[i];
            anchors[i].onclick  = function () {
                self.alterColor(this, this.color); // this is bound to anchor
                return false;     // prevent navigation
            };
        }
    }
};

 

C#
<form id="form1" runat="server">
        <div>
            <ul>
                <li><a href="www.nitinsingh.com">My Website</a></li>
                <li><a href="www.nitinsingh81.blogspot.com">My Blog</a></li>
            </ul>

            <!-- Now call the function, not in the head but below the controls -->
            <script type="text/javascript">
                anchorChange.init();
            </script>
        </div>
    </form>

This wrapper, although provides safety against mixing up functions and variables, it does not differentiate between public and private functions.

Module Pattern

Clearly distinguishes between the public and private items. Anything defined in a direct access is private, anything defined in 'return' block is public.

C#
/*  Module Pattern  */
var anchorChangeMod = function () {
    // private property
    config = {
            colors: ["#F12", "#999"]
    }

    // private method, available within 'anchorChange' class not outside
    function alterColor(link, newColor) {
        link.style.backgroundColor = newColor;
    }

    return {
        // all public code inside 'return' block
        changeColor: function(link, newColor) {
            // Calls private method inside public method
            alterColor(link, newColor);
        },

        init : function() {
            var self = this;  // assign reference to current object to 'self'

            var anchors = document.getElementsByTagName("a");
            var size = anchors.length;

            for (var i = 0; i < size; i++) {
                anchors[i].color = config.colors[i];
                anchors[i].onclick = function () {
                    // this is bound to anchor..
                    anchorChangeMod.changeColor(this, this.color);
                    return false;     // prevent navigation
                }
            }
        }
    };
}();

 

C#
<form id="form1" runat="server">
        <div>
            <div>
                <ul>
                    <li><a href="www.nitinsingh.com">My Website</a></li>
                    <li><a href="www.nitinsingh81.blogspot.com">My Blog</a></li>
                </ul>
            </div>
        </div>
        <script type="text/javascript">
            // No constructor, directly call object
            anchorChangeMod.init();
        </script>
    </form>

Revealing Module Pattern

In this, the entire structure is declared within the class block, then at end of class, have a 'return' block with the functions added to publicly exposed delegates.

C#
/*  Revealing Module  */
        function anchorChangeRev() {

            // private property
            config = {
                colors: ["#F12", "#999"]
            }

            // private method, available within 'anchorChange' class not outside
            function alterColor(link, newColor) {
                link.style.backgroundColor = newColor;
            }

            var changeColor = function (link, newColor) {
                alterColor(link, newColor);
            }

            var init = function () {
                var self = this;  // assign reference to current object to 'self'
                var anchors = document.getElementsByTagName("a");
                var size = anchors.length;

                for (var i = 0; i < size; i++) {
                    anchors[i].color = config.colors[i];

                    anchors[i].onclick = function () {
                        anchorChangeRev().cc(this, this.color); // this is bound to anchor
                        return false;     // prevent navigation
                    }
                }
            }

            return {
                // delegates to actual methods are marked as public
                cc: changeColor,
                init: init
            }
        };

 

<form id="form1" runat="server">
        <div>
            <ul>
                <li><a href="www.nitinsingh.com">My Website</a></li>
                <li><a href="www.nitinsingh81.blogspot.com">My Blog</a></li>
            </ul>
            <script type="text/javascript">
                anchorChangeRev().init();
            </script>
        </div>
    </form>

Here first is the variable through which the function gets called, second is the function delegate. Both these functions will get public scope in the final object.

Lazy Function

If we have some functionality to be run only once (often for initialization) and other repeatedly, we apply the lazy function.

We create one class and within that declare the code to be executed only once. Then within the same scope, declare the same class with the functions to be run multiple times.

/*  Lazy loading   */
        var anchorChangeLazy = function () {

            // private property
            var config = {
                colors: ["#F12", "#999"]
            };

            var anchors = document.getElementsByTagName("a");
            var size = anchors.length;

            for (var i = 0; i < size; i++) {
                anchors[i].color = config.colors[i];

                anchors[i].onclick = function () {
                    anchorChangeLazy().changeColor(this, this.color); // this is bound to anchor
                    return false;     // prevent navigation
                }
            }

            // Redefine function to hold just the changeColor function
            // which will be invoked multiple times
            anchorChangeLazy = function () {
                return {
                    changeColor: function (link, newColor) {
                        link.style.backgroundColor = newColor;
                    }
                };
            };
        };

 

<form id="form1" runat="server">
        <div>
            <ul>
                <li><a href="www.nitinsingh.com">My Website</a></li>
                <li><a href="www.nitinsingh81.blogspot.com">My Blog</a></li>
            </ul>
            <script type="text/javascript">
                anchorChangeLazy();         // just the main function, no subfunction
            </script>
        </div>
    </form>

Now whenever the class object is called, the binding in the initial code is executed only once, whereas changeColor handler (within the new class code) is made available for the usage forever.

Custom Object Constructor

We can add functions to the 'prototype' property of any object. That injects the definition into an already declared object. So the initialization function be wrapped in the constructor, and other functions added to the prototype binding.

/*  Custom object constructor  */
var anchorChangeCusCon = function() {
    this.init();
};

// 'prototype' means class definition
//  any properties can be added to this
anchorChangeCusCon.prototype.config = {
    colors: ["#F12", "#999" ]
};

anchorChangeCusCon.prototype.changeColor = function(link, newColor) {
    link.style.backgroundColor = newColor;
};

anchorChangeCusCon.prototype.init = function() {
    var self = this;

    var anchors = document.getElementsByTagName("a");
    var size = anchors.length;

    for (var i = 0; i < size; i++) {
        anchors[i].color = self.config.colors[i];

        anchors[i].onclick   = function() {
            self.changeColor(this, this.color);
            return false;
        }
    }
}


// Call of this function
var anchor = new anchorChangeCusCon();
// anchor.init();  Not needed, since this is invoked within the constructor

So we have discovered how to provide some of the OOPs principles in our own JavaScript classes for abstraction and data hiding.

Enjoy beautifying your client side code :)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)