Wednesday, June 13th, 2007

A JavaScript Module Pattern

Category: Articles, JavaScript

Eric Miraglia, of Yahoo!, has documented his explanation of what Douglas Crockford calls the JavaScript Module pattern.

Eric discusses the steps:

  • Create a namespace object: If you’re using YUI, you can use the YAHOO.namespace() method
  • Assign the return value of an anonymous function to your namespace object
  • Add “private” methods and variables in the anonymous function prior to the return statement
  • Do something useful with the pattern

  1. YAHOO.myProject.myModule = function () {
  3.     //"private" variables:
  4.     var myPrivateVar = "I can be accessed only from within YAHOO.myProject.myModule."
  6.     //"private" method:
  7.     var myPrivateMethod = function () {
  8.         YAHOO.log("I can be accessed only from within YAHOO.myProject.myModule");
  9.     }
  11.     return  {
  12.         myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty."
  13.         myPublicMethod: function () {
  14.             YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
  16.             //Within myProject, I can access "private" vars and methods:
  17.             YAHOO.log(myPrivateVar);
  18.             YAHOO.log(myPrivateMethod());
  20.             //The native scope of myPublicMethod is myProject; we can
  21.             //access public members using "this":
  22.             YAHOO.log(this.myPublicProperty);
  23.         }
  24.     };
  26. }(); // the parens here cause the anonymous function to execute and return

Note that this technique is very generic, and you can do the same thing with other frameworks, or without any frameworks!

Posted by Dion Almaer at 6:01 am

4 rating from 52 votes


Comments feed TrackBack URI

Why are the public methods set directly on the object instead of on the object’s prototype? That means if I have multiple instances of that object, they can’t share the same methods (through the prototype) and each object must carry it’s own method! That is memory intensive!

Comment by Jordan — June 13, 2007


This is meant to be a singleton pattern.

Comment by Thomas Messier — June 13, 2007

I really hope this takes off. I’ve been doing very similar for a while now, but I definitely feel like a lone man in the sea of functions only JS programming.

Comment by Ivan — June 13, 2007

Can anybody explain the advantages over simple stuff like

  1. YAHOO.myProject.myModule =
  2. {
  3.   myNotSoPrivateVar: "",
  4.   myPublicProperty: "",
  5.   myPublicMethod: function(){}
  6. };

why do i want private variables?

Comment by Teun — June 13, 2007

Might as well as why you even need objects.

Comment by Ivan — June 13, 2007

@Matthew: Yes. Yes it is. They may have just had an oversight of the post. But to their own benefit, they put the name of “module pattern” to it. It was in fact a pattern that I learned when I was at Y! so it’s all good.

Comment by Dustin Diaz — June 13, 2007

@Ivan: I don’t see how that follows. I think Teun’s question is valid, especially considering one can create private variables within Teun’s myPublicMethod() the same way one could create them within YAHOO.myProject.myModule();

Comment by Trevor — June 14, 2007


An untyped object with an anonymous constructor.

YUI loves anonymous functions and I don’t know why. It is a real pain in the neck to debug “anonymous” or “no name” in the debugger.

Now please look at the code and notice that the object’s public interface is returned. All the “public” members are at the very bottom. Is this not completely backwards?

This is Doug’s “power constructor” renamed. Doug is a nice man and I don’t hate him. It is not a good practice.

The way to enforce an entryPoint is with Function.prototype.caller. This is not very hard to do and makes a private constructor, lazy-load singleton possible.

Opera chooses to support wacky css instead of critical properties like Function.prototype.caller. Opera should fix this bug. Ian, Anne…

Function.prototype.caller can also be used to debug errors, and even build-your-own error stack by looking up the call chain. (Error.stack is natively supported in FireFox and Webkit)

Yes, Dustin, a lot of people at Yahoo do in fact use that approach and I am sure that it came from Doug. I have tried to explain my best why it is not good. I hope it makes sense to others.

Comment by Garrett — June 14, 2007

I love it how JavaScript developers are always coming up with weird patterns and conventions pretending to try and make it behave like an enterprise capable language. Actually they seem to be openly participating in a form of elitism, a close-knit club if you like.
JavaScript is a very capable OOP language, and encapsulation is one of the three tenants of OOP. Some people here say this is a singleton pattern. To me this whole construct should just be a function. I mean seriously… if you think you need private members in JavaScript you are on the wrong track. JavaScript is just a glue language for a presentation tier, no business logic.
Your “private method” is actually an anonymous function assigned to a variable inside another function i.e. a closure which should be avoided anyway. This “method” probably won’t even be called from the scope of the object instance.
And this module returns an object literal with another anonymous function?!
Excuse me but in middleware the biggest priority should be maintainability and this would seem to be a failure in that respect.

Comment by Tim Scarfe — June 14, 2007

Tim, I think you’ve missed the point of Design Patterns in general. Any language will have certain features built-in that will be Design Patterns in another language. For example, C++ has class-based inheritance built-in but prototype-based inheritance is a design pattern (see gang of four). In JavaScript the prototype-based inheritance is built-in and class-based inheritance is a design pattern. To the JavaScripter the prototype-based inheritance design pattern in “an enterprise capable language” will look like a weird pattern pretending to look like Self or JavaScript. So if someone wants to use a module in JavaScript, at least until JavaScript 2, they use a design pattern.

Comment by Peter Michaux — June 14, 2007


Actually I am an advocate of design patterns. However patterns are not designed to conceptualise missing features of a language, rather allow developers to communicate using well-known, well understood constructs for software interactions.

I realise I am being ambigious and perhaps what I have just said would back up the pattern used above.

My issue with this pattern is that it’s gratuitous. Patterns for the sake of patterns are bad because they add an unnessecary level of abstraction which only reduces maintainability further.

I guess this is pretty subjective so don’t take this as a statement, rather my opinion on the matter.


Comment by Tim Scarfe — June 14, 2007


I think that in many cases design patterns are exactly to add in “missing” features of a language. For example, Smalltalk classes all inherit from a class with Subject and Observer interfaces. Perl has modules and exporting like the pattern described here. C++ has template classes. Java has interfaces. JavaScript has prototype-based inheritance. All of these concepts could be useful at some point in another language where it is missing. People were using classes and inheritance in C before any object-oriented language had sugar for class definition.

I agree that this module pattern in JavaScript can be gratuitous at times. It doesn’t create indestructible objects with truly private/protected anything. It can keep the global name space less cluttered. It also teaches the idea of closure and automatically evaluated functions which is very useful. I use it relatively frequently when working around browser issues to produce efficient functions that don’t determine the browser-appropriate algorithm each time a function is called.

It is all subjective.

Comment by Peter Michaux — June 14, 2007

> It also teaches the idea of closure and automatically evaluated functions which is very useful.

Closures are powerful, useful, yes. Necessary here? hardly.

Knowing when not to use one is as important as knowing what a closure is.

>It can keep the global name space less cluttered.
Singleton (and this bastardized version) does little to keep the global namespace clean, though this is not really relevant to the javascript/web-paradigm, where there is library code and implementation code.

In fact, if your main goal is to keep the global nameppace clean, use a just
create one
approach (hardly necessary for most JS).

There is a much better way to write a Singleton using lazy-load approach and enforcing an entryPoint to the constructor.

One more problem with the “power constructor”: There is extra memory allocation and worse performance due to closed scope. References to inner function objects are assigned to to the public properties of a constructed object.

Closures should be used where they are needed and ONLY where they are needed. For example: event registry/broadcast adapter/change manager/notification system, or adding advice (not generally recommended). Closure is hardly necessary here.

Comment by Garrett — June 14, 2007

I made a syntactically nice version of this with support for instances as well. Check it out: (is the writeup). is the code.

Comment by Topper — August 25, 2007

I can’t stand looking at my old code that doesn’t use any of these principles. This has completely changed the way I write JavaScript.

Comment by richtaur — June 22, 2008

On mine page there is other concept of getting private members… Just check it and tell me what you think.

Comment by wilq32 — May 6, 2009

How does private methods can call public members?

Comment by loige — November 28, 2009

I find it better and more useful than what was discussed at the YUI blog. Thanks

Comment by satya61229 — July 22, 2011

This pattern is one of the most useful patterns I’ve ever learnt. I truly respect Douglas Crockford as a good teacher, and thanks Aajxian for this great post.

Comment by saeedneamati — October 17, 2011

Leave a comment

You must be logged in to post a comment.