Java Script Patterns

DesignPatterns solve many recursive problems that are encountered in an elegant way. However, most are defined for class-based languages. Since JavaScript is a PrototypeBasedLanguage, we can face problems in implementing many of these patterns. But with JavaScriptCodingStandard and some fixing of code, we can overcome this problem. Note that there is a more efficient way to do these patterns. The optimal implementation is left as an exercise for the reader. Some suggestions are:

SingletonPattern

I think this is one of the most used (and misused) patterns. The following code tries to use SingletonPattern in JavaScript.
	// Handles events for the GUI framework.
	EventHandler.instance_	= new EventHandler();
	EventHandler.getInstance = EventHandler_getInstance;

// Constructor. function EventHandler() { if(EventHandler.instance_!=null) alert("Cannot make multiple instances!"); }

// Returns singleton instance. function EventHandler_getInstance() { return EventHandler.instance_; }
You can also use closure to make a singleton. Here is an example:
	var ASingleton = function() {
		var AConstructor = function AConstructor() {
			this.name = "John Criton";
			this.occupation = "Pain in the Butt";
		};

var instance = new AConstructor();

return function () {return instance;}; }();

// Make some singletons // no need for getinstance functions var vv = new ASingleton(); var ww = new ASingleton();

// true if same object, otherwise false window.alert(vv === ww);
Here, the sole instance is constructed when declaring the function. You can also force it to construct the instance using LazyInitialization.

The following can also be considered a simple Singleton.
    var aSingleton = {
      name: "John Criton",
      occupation: "Pain in the Butt",
      toString: function() {
        return this.name + " is a " + this.occupation;
      }
    }
The version you choose for your project depends on its requirements, complexity, and your personal coding style.

AbstractFactory pattern

AbstractFactory creates instances of another class. This adds flexibility in the code such that the calling class is not directly linked to the class whose instance it needs. In browser world this pattern is a boon! An example.

	// Factory of GuiComponent.
	GuiComponentFactory.instance_ = new GuiComponentFactory();
	GuiComponentFactory.getInstance = GuiComponentFactory_getInstance;

function GuiComponentFactory() { if(GuiComponentFactory.instance_!=null) alert("Cannot make multiple instances!"); this.createGuiComponent = GuiComponentFactory_createGuiComponent; }

function GuiComponentFactory_getInstance() { return GuiComponentFactory.instance_; }

function GuiComponentFactory_createGuiComponent() { if(Browser.getInstance().getType()==Browser.NETSCAPE) return GuiComponentFactory_createNetscapeGui(); return GuiComponentFactory_createNormalGui(); }

function GuiComponentFactory_createNetscapeGui() { return new NetscapeGuiComponent(); }

function GuiComponentFactory_createNormalGui() { return new GuiComponent(); }

PrototypePattern

This is one of the easiest patterns for JavaScript, since it is built into the language:
	var APrototype = function() {
		this.name = "John Criton";
		this.occupation = "Pain in the Butt";
		this.toString = function() {
			return this.name;
		};
	};

var AClient = function() { this.toString = function() { return this.occupation; }; }; AClient.prototype = new APrototype();

// Make a client var vv = new AClient(); window.alert(vv);
While not strictly like the GangOfFour's intent, Prototypes can be used to implement the TemplateMethodPattern in JavaScript as well:
	var APrototype = function() {
		this.toString = function() {
			return this.step1() + this.step2() + this.step3();
		};
	};

var AClient = function() { this.step1 = function() {return "John Criton";}; this.step2 = function() {return " is ";}; this.step3 = function() {return "a pain in the butt!";}; }; AClient.prototype = new APrototype();

// Make a client var vv = new AClient(); window.alert(vv);

DecoratorPattern

You can also use the prototype property to decorate an object with new responsibilities without changing the base object:
	// Decorates a W3C DOM Level 1 document object
	var DecoratedDocument = function(doc) {
		var Constructor = function() {
			this.popupTitle = function() {
				window.alert(this.title);
			};
		};
		Constructor.prototype = doc;
		return new Constructor();
	};

// Make a client window.onload = function() { var vv = new DecoratedDocument(window.document); vv.popupTitle(); };


Tip

The DocumentObjectModel contains many more examples of common DesignPatterns.

I'm curious why you would say JavaScript is a difficult language. I find it to be one of the most flexible and easy to work with and most powerful of just about any language. It supports autodelegation via PrototypeBased objects, DynamicTyping rather than StaticTyping, optional parameters in a standard argument list, full LexicalClosures - frankly, it's almost LispLanguage in CeeLanguage's clothing. If you like ObjectOriented and FunctionalProgramming, you should absolutely love JavaScript: it's a wonderful little language.

As you've observed, Lisp provides a superset of the semantics of JavaScript. Lisp is supported, documented, mature, and has a sparse, expressive, and trivially-parsed syntax. JavaScript, conversely, buries much or all of Lisp's semantics beneath a baroque syntax and horribly antiquated tools. Far from being a "wonderful little language", I find it a cheap imitation. -- TomStambaugh

It may be a cheap imitation of Lisp, but then again, what isn't? The fact is it's a language we can actually use in our day-to-day work and it has many of Lisp's niceties. Can't really complain about that.

JavaScript is seen as CommonLisp with another syntax: http://lambda-the-ultimate.org/classic/message8778.html


CategoryJavaScript

EditText of this page (last edited November 5, 2010) or FindPage with title or text search