Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
145 lines (118 sloc) 5.33 KB
<!DOCTYPE html>
An exploration of the Module Pattern, a useful method for encapsulation in
If you want to learn more about JavaScript and "the right way" to write it,
read The Good Parts, by Douglas Crockford. I can't recommend it enough.
Note that this is NOT the only way to implement the Module Pattern. It is,
however, my favorite way. I prefer it because it's simple to implement,
easy to read, and avoids a lot of the JavaScript-specific concepts that
trip up developers unfamiliar with the language.
Steve Kwan
Originally from my GitHub:
Date: Feb 21, 2013
// The module pattern is a good way to encapsulate your JavaScript functions
// and properties. The example below shows how to create a module, namespace
// it, and specify public/private properties and functions.
// Be aware that the Module Pattern is NOT generally used for object-oriented
// programming. It does not give you the ability to define a class that can
// spawn objects based on its definition. Although it is possible to jerry
// rig the Module Pattern to define classes, there isn't a real benefit to
// doing this as JavaScript has another facility for this.
// If you are more interested in laying out a classical object-oriented
// hierarchy, look at this example instead:
// However, be aware that JavaScript is not a classically object-oriented
// language. If you are trying to write true classical OOP in JavaScript,
// you're probably doing it wrong. :)
// Advantages of the Module Pattern:
// -Avoids nonsense with the "this" keyword, which often causes confusion
// -Gives you basic encapsulation without having to write a lot of code
// -If you are creating a singleton "class," the Module Pattern is for you.
// Disadvantages of the Module Pattern:
// -True class-based OOP doesn't work well with the Module Pattern.
// First, let's create a namespace. It's not required, but it's usually a
// good idea.
var MyNamespace = MyNamespace || {};
// Let's add our module to the namespace. Basically, it's just a property of
// the namespace. Note that our module is actually a function. We're going
// to use JavaScript closures to emulate private methods, which are not
// natively part of JavaScript.
MyNamespace.MyModule = function()
// Let's define a private and public property. Note that we define them in
// exactly the same way. The bit that specifies whether they are
// public/private comes later...
var myPrivateProperty = 2;
var myPublicProperty = 1;
// Let's declare a simple private function.
var myPrivateFunction = function()
// Now let's declare a public function. Again, note that the function
// definition is exactly the same as the private one.
var myPublicFunction = function()
// Just for fun, let's call our private function. Note that while we are
// inside the module, we have full access to all Module properties and
// functions, just like if we were inside a class.
// Let's make a setup function for this module: something that is called
// once when it's loaded. I generally like to call my setup functions
// init().
var init = function()
// Do some setup stuff
// This is the part that separates the private and public stuff. Anything
// in this object becomes public. Anything NOT in this object becomes
// private.
var oPublic =
init: init,
myPublicProperty: myPublicProperty,
myPublicFunction: myPublicFunction
return oPublic;
// This is the interesting part: we are returning our oPublic interface, and
// immediately invoking our MyModule function with the () at the end.
// We do this because we are not actually saving the function we created; we
// are saving the RESULT of the function. The () makes us immediately call
// the function, and it is the result we save. The original function itself
// is discarded...but its contents live on via JavaScript closures!
// MyModule is not the function we have defined; rather, it is the result of
// an anonymous function that was called once and discarded. Because that
// function doesn't have a name, we can't refer to its internal properties
// directly. And that's why the properties NOT in the oPublic interface
// become private. :)
// Let's call our setup function....
console.log("Calling init()...");
// And our public function. Internally, this will call myPrivateFunction.
// This wil work because it's being called from inside the module.
console.log("Calling myPublicFunction()...");
// This will throw an error because myPrivateFunction() is not accessible
// from outside the module.
console.log("Calling myPrivateFunction()...");