Omarrr

Javascript Module Pattern: A Detailed Deconstruction

The term module is a convention used in Javascript to group code that’s conceptually coherent. The Module Pattern is a programming design pattern that uses modules as the basic construct for organizing code.

Javascript Module Pattern by omarrr

Wikipedia defines Modular Programming as follows

[…] a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality.

The basic module

The absolute most basic Javascript module is actually a Javascript object

var Module = {
    foo: 'hello world'
}

By itself this doesn’t seem like a very useful pattern but just by grouping under this object all variables needed we can get a great replacement for global variables

var Module = {
    foo: 'hello world',
    bar: 12345,
    baz: ["John", "Joe", "Josh"],
    qux: {x: 100, y: 300}
}

The Object-Module Pattern

Javascript object keys can hold functions also, which means that this simple module is a quick way to package our code consisting of both variables and functions.

var Module = {
    foo: 1
    bar: function() {
        console.log(foo); // ReferenceError: foo is not defined
        console.log(this.foo); // 1
        console.log(Module.foo); //1
    }
};

Public access

Variables defined as in the example above are public and can be access directly

Module.foo = 3;
Module.bar();

Within the module’s bar the value of this equals Module, which means that the following two lines are equivalent when used inside bar

console.log(this.foo);
console.log(Module.foo);

Trying to access foo without the this qualifier or the namespace Module will throw a Reference error since there is no foo global variable defined.

Dynamic content

Modules allow for new variables to be added on the fly. This code is ok even if we’ve never declared the qux member before.

Module.qux = 2;

This simple module pattern is more a Javascript code grouping technique. It is the most basic example of Javascript namespacing and a good replacement for using any global variable. You should always be able to replace all your global variables and functions for this code:

var MyNamespace = {};

MyNamespace.qux = "my new namespaced var (aka global)"

Full Example

Here’s a complete example of this Module Type:

var Module = {
    foo: 1
    bar: function() {
        console.log(this); // ok! (=Module)
        console.log(++this.foo); // ok!
        console.log(++Module.foo); // ok!
    }
};

// Public access
console.log(++Module.foo); // ok!
Module.bar();

// Allows for new variables to be added on the fly
Module.qux = 2;

The Functional-Module Pattern

The Functional-Module Pattern is very similar to the Object-Module described above, but instead of creating an object directly through the object notation, we create it as a result of executing a function.

Compare

var Module1 = {
    foo: 10,
    bar: function(){ alert("hi");}
}

with

var Module2 = (function(){
    return { 
        foo: 10,
        bar: function(){ alert("hi");}
    };
}());

both Module1 and Module2 define an identical object, but utilizing the second syntax we can take advantage of closures.

The Closure-Module Pattern

A Closure is a function, plus the environment (or scope) it was declared in. Only functions, created inside functions are closures, and they can make our objects a tad more powerful and a lot more secure by:

  • Data encapsulation: providing private member fields and methods
  • Persistence of local scope: allowing public and private methods access to a private scope unique to the Module at hand

Implementing Private Members

In the example below the variable _foo can be considered as a private member:

var Module = (function(){
    var _foo = 20;
    return { 
        bar: function(){ alert("hi");}
    };
}());

_foo is inaccessible to external code and so this code will return undefined’

console.log(Module._foo); // undefined

(By the way, naming private variables starting with _ is a good common practice to easily differentiate between public and private variables and functions).

Taking advantage of the local scope

bar in the example above, however, is truly private and could be used with in the public (and private) functions declared inside Module. See the example below:

var Module = (function(){
    var _foo = 20;
    return { 
        bar: function(){ console.log(_foo);}
    };
}());

Calling the public method bar of Module will output the value of _foo, however trying to access the value directly from outside of Module will now work

Module.bar(); // 20
console.log(Module._foo); // undefined

We have effectively created a private variable that’s inaccessible to code outside of Module that can be used by internal functions for keeping the local state.

Closures are great when writing APIs and code to be used by other developers while keeping the integrity of the API itself.

Dynamic Members

The Module Pattern permits us to have, not only public and private members, but also dynamic variables and functions. Since the returned Module is a regular Javascript object we can extend it as we would normally do in Javascript

Module.qux = 20;
Module.qux = function(){ console.log(this.qux); };

The —so called— Constructor

So up until now I’ve used this format of the Module pattern:

var Module = (function(){
    var _foo = 0;

    return {
        bar: 1,
    }
}());

I personally find that using a more explicit format makes it more clear to read and understand. Here:

var Module = (function(){
    var _foo = 0;

    var self = {
        bar: 1,
    }

    return self;
}());

In this case it is clear that the value of Module is the object selfreturned by the function. This is informally called the constructor of the Module.

Even better, this exact same thing can be expressed as:

var Module = (function(){
    var _foo = 0;

    var self = {};

    self.bar = 1;

    return self;
}());

I like this last representation best since it consists mostly of regular Javascript functional expressions (vs. object notation).

Self-referencing

Using this —so called— constructor syntax gives us a way to reference the module itself from within the module’s private member functions. Without a variable self a private method would have no means to call a public variable or function.

Self-referencing varies depending on the scope of the caller and the callee. What this means is that in order to call a function of a module we must understand the scope of the function that’s calling and the function that’s being called, since there are rules for each.

Private access within a Module

Accessing private members can be done directly without any qualifier from private or public functions. Dynamic functions can’t access private members.

var Module = (function(){
    var _foo = 10;
    var _bar = function (){ console.log(_foo)};

    var self = {
        baz: function (){ console.log(_foo)};
    }

    return self;
}());

Public access within Module

Accessing public members from within private or public functions can be done using the self variable. Additionally public functions can also access public members via this’ keyword.

var Module = (function(){
    var _foo = function (){ console.log(self.bar)};

    var self = {
        bar: 1,
        baz: function (){ console.log(self.bar)}; // this works
        qux: function (){ console.log(this.bar)}; // this works too
    }

    return self;
}());

Access from within dynamic members

Dynamic functions must always use the keyword this to access public and other dynamic members. This is one of the awesome things about Javascript closures. Since the dynamic functions were not in the same scope as the Module itself when created, they don’t have access to private methods (not even self). That means that developers can’t use dynamic members to get around the private scope limitations.

var Module = (function(){
    var _foo = 10;

    var self = {
        bar: 20,
    }

    return self;
}());

Module.qux = (function(){ 
    console.log(this._foo); // undefined
    console.log(this.bar); // 20
});

Summary

There are several ways to express the Module patter and all of them are equivalent. In any case taking advantage of closures will make modules that much more powerful.

Closure-based Pattern

This is the minimum expression of the Module Pattern. I personally like this syntax best, since I believe it offers best readability:

var m = (function(){
    var _foo = "I'm private";

    var self = {};

    self.bar = "I'm public";

    return self;
}());

A complete example: All put together

Here’s a complete example that shows public and private variables and functions.

var Module = (function(){
    // private variables
    var _v1 = 10;

    // private methods
    var _f1 = function(){ 
        console.log(_v1);
        console.log(self.v2);
        console.log(self.v3);
    };

    // constructor
    var self = {};

    // public variables
    self.v2 = 20;

    // public functions
    self.f2 = function(){
        console.log(_v1);
        console.log(self.v2);
        console.log(self.v3);
    };

    return self;
}());

// Dynamic Members
Module.v3 = 30;
Module.f3 = function(){ 
    console.log(this.v2); 
    console.log(this.v3); 
};

// Usage
console.log(Module.v2);
Module.f2();
console.log(Module.v3);
Module.f3();

References

September 6, 2013 ☼ code