Web Development for 2010

Alexander Dickson - Web Developer covering PHP, jQuery / Javascript, XHTML, CSS, more

A new way of creating objects in JavaScript

Filed under jQuery / JavaScript. Published on Thursday, 8th October 2009.

Although I've been using JavaScript for years, the way I've gone about it has evolved greatly over time. There are a few methods of creating objects that I would like to explain. I'm going to demonstrate the different ways by doing the same thing, that is, a simple wrapper for the console.log() method provided by Firebug. It will allow you to call init() to initialise wther the wrapper will use console.log() or alert(), and it will provide public methods to addMessage(), print() and printAll().

The object literal

This is the first method I tried after leaving the world of procedural programming and global functions. It is an object literal of functions and variables.

var superLog = { allMessages: [], useAlert: false, init: function() { if (typeof console == 'undefined' || typeof console.debug != 'function'){ this.useAlert = true; }; }, display: function(message) { if (this.useAlert) { alert(message); } else { console.log(message); }; }, print: function(message) { this.display(message); }, addMessage: function(message) { this.allMessages.push(message); }, printAll: function() { var noMessages = this.allMessages.length - 1; var allMessagesConcat = ''; for(var i=0; i<=noMessages;i++) { allMessagesConcat += this.allMessages[i] + '\n'; }; this.display(allMessagesConcat); } };
The object literal of our superLog object.

I'm no longer a huge fan of this method. For one, you can not have private and public methods. In the example above, the display() should be a private method. It is also a pain in my opinion to have everything comma separated, which can introduce errors from missed commas.

Douglas Crockford's pattern

This pattern is based off Douglas Crockford's pattern for creating objects. It allows for private and public methods. Hiding methods and variables is a great way to enforce data integrity.

var superLog = function() { var allMessages = []; var useAlert = false; var display = function(message) { if (useAlert) { alert(message); } else { console.log(message); }; }; return { init: function() { if (typeof console == 'undefined' || typeof console.debug != 'function'){ useAlert = true; } }, print: function(message) { display(message); }, addMessage: function(message) { allMessages.push(message); }, printAll: function() { var noMessages = allMessages.length - 1; var allMessagesConcat = ''; for(var i=0; i<=noMessages;i++) { allMessagesConcat += allMessages[i] + '\n'; } display(allMessagesConcat); } }; }();
Douglas Crockford's method of creating objects.

This pattern is cleaner in my opinion then the first, although it does rely on comma seperated methods. Remember to include the opening and closing parenthesis at the end to self invoke the function.

Revealing module pattern

A clever bloke named Christian Heilmann has also put his own spin on Crockford's pattern, a spin that I (and perhaps you) welcome.

It is essentially the same thing, only instead of returning an object literal of functions, you return an object literal of the names of the methods you'd like to make public. Observe!

var superLog = function() { var allMessages = []; var useAlert = false; var display = function(message) { if (useAlert) { alert(message); } else { console.log(message); }; }; var init = function() { if (typeof console == 'undefined' || typeof console.debug != 'function'){ useAlert = true; }; }; var print = function(message) { display(message); }; var addMessage = function(message) { allMessages.push(message); }; var printAll = function() { var noMessages = allMessages.length - 1; var allMessagesConcat = ''; for(var i=0; i<=noMessages;i++) { allMessagesConcat += allMessages[i] + '\n'; } display(allMessagesConcat); }; return { init: init, print: print, addMessage: addMessage, printAll: printAll }; }();
The revealing module pattern

In my opinion, this one is the best of both worlds. Not only do you get method and variable visibility, but you don't have to succumb to a large list of methods in an object literal.

In conclusion

It's really a matter of personal taste. I know what I like, and I hope these few examples have shown you the possibilities of objects in JavaScript. Stay tuned for an amendment of this article!

Comments

  • Alexander Dickson

    Posted on Monday, 19th October 2009 @ 11:59pm.

    @miles Thanks for the feedback. In regards to the last code example, I think it increases readability when glancing at the function. You can quickly deduce which methods are meant to be public (you get a nice list). Of course, different methods suit different people.

    You're right about the variable - it was a typo, and has been fixed. Regarding the function not being original - I never set out to make it such.

    Have a splendid day!

  • miles

    Posted on Monday, 19th October 2009 @ 11:42pm.

    First of all, how did that guy improve or "spin" crockfords design? All he did was increase the verbosity of the code.

    Also, in your attempt to provide something original (which you dont), you have a typo. The variable "userAlert" is probably supposed to be "useAlert", based off the other code you have.

    > "This is the first method I tried after leaving the world of procedural programming and global functions. It is basically just an object literal of functions and variables."
    should probably read, "This is just an object literal".

Leave a Comment

Comment Details

Your email will never be displayed. If you have a gravatar, it will be displayed.

Note: Your comment may require approval before it is posted to the site.

Stack Overflow Profile

view full profile »

About

I'm a web developer from the Sunshine Coast, Australia. more »