Benefits
The Module Pattern keeps things very simple and easy to read and use. We can use Objects in a very cool way, and doesn’t make swollen your code with repetitive “this” and “prototype” declarations.
Starting with the Module
In order to understand what a Module can do, we need to keep present the definition of “closure” and “scope” we will need to understand what the following function does:
1 2 3 |
(function () { // our js code })(); |
Closure
Is a local variable from inner-function scope, that is keeping the reference alive after the function return
Scope
Is an space inside every function in javascript, where variables and functions exists. There variables and functions are not visible outside this scope.
What the function does:
- Creates an Anonymous function: a function with-out a namespace declaration
- Creates Immediately-Invoked-Function-Expressions: Declares a function, which then calls itself immediately. Creating new scope, different to the global scope, thats wrap all our function logic inside them to return only what we really needs.
Accessing our new Module
After the new scope has been created, we need to namespace our code so that we can access any methods we return.
1 2 3 |
var fooModule = (function () { // our namespace js code })(); |
This is our new Module, we can access it directly from the global scope using the namespace. As you can see this is not safe, so let’s make this more safe and private
The Private methods
Module scope to make our methods inaccessible outside of that scope. In order to achieve this we are going to encapsulate or group ‘private and ‘public’ members.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
fooModule = (function(){ // locally scoped Object var myObject = {}; //Private members (_) _pp = ''; // _private properties _pm = function(){}; //_private methods var myObject = { //Public members pp: '', //public properties pm: function(){} // public methods } return myObject })(); |
calling Object Literal
1 |
fooModule.pm; |
This is where the Module comes in to save us, by allowing us to define all our private stuff locally and only return “the good parts”.
Create a namespace to wrap our Object
1 2 |
// Create a namespace that will wrap our object var Foo = {}; //namespace |
Add public methods
1 2 3 4 5 |
// Add public methods to the object Foo.CssControl = { addCSS: function(id, url){ } } |
Extending methods
This idea gives us access to our Object to extend, that’s to say, have all the benefits of private scoping/functionality and then return our extension method
1 2 3 4 5 |
var fooModule2 = (function (fooModule) { // access to fooModule scope })(fooModule); |
Create private members
To create private members, we have to use Closures. This helps us to create a private space.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Foo.CssControl = (function(){ // Private members var n1 = 'im private', n2 = function(id, url){ } return { // closure // Public members (returned) addCSS: function(id, url){ } } })(); |
What we have done is created a Closure that looks like a self executing anonymous function that returns the public methods we added earlier.
using the public methods
1 |
Foo.CssControl.addCSS("myCSS", "foo.css"); |
Module Pattern limitations
One limitation of the module pattern so far is that the entire module must be in one file. Anyone who has worked in a large code-base understands the value of splitting among multiple files. Luckily, we have a nice solution to augment modules. First, we import the module, then we add properties, then we export it