JavaScript: The Module Pattern
May 28, 2008
I had a question from one of my coworkers a few weeks back about some basic OO techniques in JavaScript. Seeing as this is a key question from most people getting into JS from a classical OO background I thought I might just share a powerful little concept called the “Module Pattern” to get you all started.
The module pattern (first identified by Douglas Crockford) exploits the fact that JS only has one kind of scope: function scope. Forget blocks, or any other kind of scope resoultion techniques you might know from other programming languages – it ain’t here. JS allows you create functions within functions (i.e. nest them), and hence function scope is also nested. Any nested function can see anything in the parent function and so on up the tree. It does this through the use of closures which is far to big a topic for this short article, you’ll just have to accept the fact that it works.
Okay so why is this important? Well JS has a major flaw (some would say feature) in that it doesn’t have any sort of PPP (public, private, protected) functionality. Everything is public. Everything. So how do we achieve any sort of meaningful encapsulation you ask? Isn’t information hiding critical to the design principle “open for extension, closed for modification”? Well the module pattern is one solution to this problem.
Here’s how it works:
MyObject = function() {
var myPrivateField;
function myPrivateMethod(someValue) {
// look ma I'm a closure
myPrivateField = someValue;
// assigning a private member to a public one
pub.myPublicField = myPrivateField;
return "I'm a private method";
}
/*
* this is where we define the object's public
* interface using another bit of JS
* magic: the object literal
*/
var pub = {
myPublicField: null,
myPublicMethod: function() {
return "Hello World!";
},
myPrivateMethodWrapper: function(someValue) {
// calling a private/hidden method
return myPrivateMethod(someValue);
}
}
// here we override the constructor's return value
// with our public interface object
return pub;
}
var o = new MyObject();
o.myPrivateMethod(); // wont work it's private/hidden
o.myPublicMethod(); // works!
I know that this will completely weird out some of you OO purists, but when JS is the only thing you’ve got (e.g. in the browser) it’s a pretty useful technique for gaining some sort of PPP control over your objects API.
July 4, 2010 at 9:46 am
[...] Javascript: The Module Pattern [...]
July 14, 2011 at 11:28 pm
Hello,
great article. But I found 2 errors when I was testing the code:
- Add a comma between myPublicMethod and myPrivateMethodWrapper member definitions.
- Add “return” to myPrivateMethod(someValue), inside myPrivateMethodWrapper member definition.
Cheers
July 26, 2011 at 6:51 am
Thanks for the feedback Sergio, you’re absolutely right. Updated the post with your suggestions.