JavaScript Programming Patterns

Since I have started working at Yahoo! mid of May, I got in contact with some advanced JavaScript programming techniques. I got a bit confused at first, cause e.g. using a singleton in JavaScript was kind of a new to me. So I did some testing and evaluation on the different coding techniques that I got confronted with and tried to grasp what kind of pattern actually does what.

Update (September 8, 2007): This post has been rewritten, extended and turned into an article which can now be found in the Code Section.

I made up a simple exercise: Say, you have a link on a page and when clicking the link, the background color should change to orange. The markup looks like this:

<a id="thisLink" href="http://news.bbc.co.uk/">News on BBC website</a>

As follows, I used 3 different approaches to tackle this problem with JavaScript. I am sure that there are more options, but – as usual – if you have any comments on the following demo, please feel free to give feedback.

1. Singleton

The first solution deals with creating a singleton, which means creating one object, whose properties are immediately available for use. To create an object in JavaScript you use the following syntax:

var testObject = {};

For a start, I created an empty singleton:

anchorChange1 = {};

I decided to create 3 different properties for this object:

  • config: holds some general configuration parameters
  • alterColor: method which does the actual color change
  • init: attaches the alterColor function to the link element

The config property holds the Id of the link and the new background color:

config: {
    linkId: "thisLink",
    newBgColor: "#F93"
}

alterColor changes the background color to the new color:

alterColor: function (linkObj) {
    linkObj.style.backgroundColor = this.config.newBgColor;
}

init is responsible for linking the onclick event to the alterColor method

init: function () {
    var link = document.getElementById(this.config.linkId);
    link.onclick = function () {
        anchorChange1.alterColor(this);
        return false;
    }
}

The final singleton looks like this:

anchorChange1 = {
    config: {
        linkId: "thisLink",
        newBgColor: "#F93"
    },

    alterColor: function (linkObj) {
        linkObj.style.backgroundColor = this.config.newBgColor;
    },

    init: function () {
        var link = document.getElementById(this.config.linkId);
        link.onclick = function () {
            anchorChange1.alterColor(this); 
            return false; 
        }
    }
};    

In a JavaScript block on the page – after the anchor and preferably close to the closing body-tag (as recommended by Douglas Crockford) – you then only need to call the init-function:

<script>
anchorChange1.init();
</script>

To see this in action, please proceed to the working example, with additional comments in the JavaScript part.

2. Module Pattern

Taking the singleton pattern one step further leads us to what Douglas Crockford calls the “module pattern”. The idea is to have an encapsulated module, that cannot conflict with any other modules you or someone else has created. You can create public and private methods within that module.

First, lets create a function that gets executed immediately (which is caused by parens after the closing curly bracket):

anchorChange2 = function () {}();

As stated before, with this programming pattern, you can have public and private methods. Public methods can be accessed from outside, private methods only from within the object. I decided to have a private method alterColor, which does the actual color change, and 3 public properties, which are bound to the object itself. For this to happen, you return an object with the respective properties:

return {
    config: {
        linkId: "thisLink",
        newBgColor: "#F93"
    },

    changeColor: function (linkObj) {
        alterColor(linkObj);
    },

    init: function () {
        var link = document.getElementById(this.config.linkId);
        link.onclick = function () {
            anchorChange2.changeColor(this); 
            return false; 
        }
    }
}

The alterColor function lives within the parent function anchorChange2, but outside the returned object:

function alterColor (linkObj) {
    linkObj.style.backgroundColor = anchorChange2.config.newBgColor;
}

As alterColor is a private method, it cannot be accessed from outside. To be able to execute that function you either need to put it in the object (which will basically lead you to using the singleton pattern again), or create another property within the returned object that calls the method. I have done the latter.

The final code for this pattern looks like this:

anchorChange2 = function () {
    // private method
    function alterColor (linkObj) {
        linkObj.style.backgroundColor = anchorChange2.config.newBgColor;
    }

    return {
        //public property
        config: {
            linkId: "thisLink",
            newBgColor: "#F93"
        },

        //public method
        changeColor: function (linkObj) {
            // calls private method to change color
            alterColor(linkObj);
        },

        //public method
        init: function () {
            var link = document.getElementById(this.config.linkId);
            link.onclick = function () {
                anchorChange2.changeColor(this); 
                return false; 
            }
        }
    }
}();

As with the general singleton example above, in the body of the html document you would then need to call the init method:

<script>
anchorChange2.init();
</script>

Please proceed to the working example. The source code is, again, annotated with comments to hopefully make clear what is happening.

3. Custom Objects

The method of creating a new object of a class (instantiating it) is common in all object-oriented languages. But JavaScript is object-based rather than object-oriented. In JavaScript, you just need to call the constructor function of your (custom) object with respective parameters to create an object. You do not have any classes or subclasses as e.g. in Java.

First, we would need to create a constructor function for our object:

anchorChanger = function (link, color) {
    this.link = link;
    this.color = color;   
}

Additionally, I would need an init method and the actual changeColor method which does the background color swap.

this.changeColor = function () {
    this.link.style.backgroundColor = this.color;
};

this.init = function () {
    this.link.onclick = function () {
        changer.changeColor();
        return false;
    }
};

The final custom object looks like this:

anchorChanger = function (link, color) {
    this.link = link;
    this.color = color;

    this.changeColor = function () {
        this.link.style.backgroundColor = this.color;
    };

    this.init = function () {
        this.link.onclick = function () {
            changer.changeColor();
            return false;
        }
    };
}

What is left to do to make this work is to create a new object and call its init method. This is done in a script-block on the page:

<script>
var link = document.getElementById("thisLink");
var changer = new anchorChanger (link, "#F93");
changer.init();
</script>

As with the examples before, you can check out a live demo together with comments.

Conclusion

As stated above, these are my assumptions on how this particularly simple task can be accomplished. I am sure that there are some other ways of approaching this problem, but my point in going through these exercises was to teach myself how these different methods work in general.

There is no general solution on how such problems should be approached. For a task like this, I believe that the singleton pattern is the most convenient way of doing it. Mostly because less lines of code are required. But for other, more complex problems, using the module pattern or creating custom objects might be more appropriate.

Thanks for reading and checking out the examples. I would be very happy if you could provide me with feedback by leaving a comment or by sending an email.

Related Reading