Revealing Module Pattern - Techniques, Strategies and Patterns for Structuring JavaScript Code

Using the JavaScript Revealing Module Pattern

This is the 3rd post in a series on techniques, strategies and patterns for writing JavaScript code.The Prototype Pattern shown in an earlier post works well and is quite efficient, but it’s not the only game in town. One of my favorite overall JavaScript patterns is the Revealing Module Pattern since it’s cleaner with less usage of the “this” keyword. I also like the fact that it doesn’t separate code into constructor and prototype sections. Although it doesn’t offer the benefit of sharing functions implementations across objects through JavaScript’s prototype feature, it’s definitely a viable option.

As a quick review, I showed the following code in the first post since it shows “function spaghetti code” and illustrates code that can be encapsulated into a more re-useable object. The code simply lists all functions directly with no encapsulation and defines several global variables. While the code works fine this way, I’ll examine how we can restructure it to follow the Revealing Module Pattern.

window.onload = function () {
    eqCtl = document.getElementById('eq');
    currNumberCtl = document.getElementById('currNumber');
};

var eqCtl,
    currNumberCtl,
    operator,
    operatorSet = false,
    equalsPressed = false,
    lastNumber = null;

function add(x,y) {
    return x + y;
}

function subtract(x, y) {
    return x - y;
}

function multiply(x, y) {
    return x * y;
}

function divide(x, y) {
    if (y == 0) {
        alert("Can't divide by 0");
        return 0;
    }
    return x / y;
}
     
function setVal(val) {
    currNumberCtl.innerHTML = val;
}
        
function setEquation(val) {
    eqCtl.innerHTML = val;
}
        
function clearNumbers() {
    lastNumber = null;
    equalsPressed = operatorSet = false;
    setVal('0');
    setEquation('');
}

function setOperator(newOperator) {
    if (newOperator == '=') {
        equalsPressed = true;
        calculate();
        setEquation('');
        return;
    }
            
    //Handle case where = was pressed
    //followed by an operator (+, -, *, /)
    if (!equalsPressed) calculate();
    equalsPressed = false;
    operator = newOperator;
    operatorSet = true;
    lastNumber = parseFloat(currNumberCtl.innerHTML);
    var eqText = (eqCtl.innerHTML == '') ? 
        lastNumber + ' ' + operator + ' ' : 
        eqCtl.innerHTML + ' ' + operator + ' ';
    setEquation(eqText);
}

function numberClick(e) {
    var button = (e.target) ? e.target : e.srcElement;
    if (operatorSet == true || currNumberCtl.innerHTML == '0') {
        setVal('');
        operatorSet = false;            
    }
    setVal(currNumberCtl.innerHTML + button.innerHTML);
    setEquation(eqCtl.innerHTML + button.innerHTML);
}

function calculate() {
    if (!operator || lastNumber == null) return;
    var currNumber = parseFloat(currNumberCtl.innerHTML),
        newVal = 0;
    //eval() would've made this a whole lot simpler
    //but didn't want to use it in favor of a more
    //"robust" set of methods to demo patterns
    switch (operator) {
        case '+':
            newVal = add(lastNumber, currNumber);
            break;
        case '-':
            newVal = subtract(lastNumber, currNumber);
            break;
        case '*':
            newVal = multiply(lastNumber, currNumber);
            break;
        case '/':
            newVal = divide(lastNumber, currNumber);
            break;
    }
    setVal(newVal);
    lastNumber = newVal;
}

 

The Revealing Module Pattern is based on a pattern referred to as the Module Pattern. It makes reading code easier (in my opinion anyway) and allows it to be organized in a more structured manner. The pattern starts with code like the following to define a variable, associate it with a function and then invoke the function immediately as the script loads. The final parenthesis shown in the code cause it to be invoked.

var Calculator = function () { /* Code goes here */ }();


Variables and functions that should be encapsulated within the Calculator object go in the “Code goes here” section. What’s really nice about the pattern is that you can define which members are publicly accessible and which members are private. This is done by adding a return statement at the end of the function that exposes the public members. The following code demonstrates how the Calculator functionality can be refactored to follow the Revealing Module Pattern:

 

var Calculator = function () {
    var eqCtl,
    currNumberCtl,
    operator,
    operatorSet = false,
    equalsPressed = false,
    lastNumber = null,

    init = function (equals, currNumber) {
        eqCtl = equals;
        currNumberCtl = currNumber;
    },

    add = function (x, y) {
        return x + y;
    },

    subtract = function (x, y) {
        return x - y;
    },

    multiply = function (x, y) {
        return x * y;
    },

    divide = function (x, y) {
        if (y == 0) {
            alert("Can't divide by 0");
            return 0;
        }
        return x / y;
    },

    setVal = function (val) {
        currNumberCtl.innerHTML = val;
    },

    setEquation = function(val) {
        eqCtl.innerHTML = val;
    },

    clearNumbers = function() {
        lastNumber = null;
        equalsPressed = operatorSet = false;
        setVal('0');
        setEquation('');
    },

    setOperator = function(newOperator) {
        if (newOperator == '=') {
            equalsPressed = true;
            calculate();
            setEquation('');
            return;
        }

        //Handle case where = was pressed
        //followed by an operator (+, -, *, /)
        if (!equalsPressed) calculate();
        equalsPressed = false;
        operator = newOperator;
        operatorSet = true;
        lastNumber = parseFloat(currNumberCtl.innerHTML);
        var eqText = (eqCtl.innerHTML == '') ?
            lastNumber + ' ' + operator + ' ' :
            eqCtl.innerHTML + ' ' + operator + ' ';
        setEquation(eqText);
    },

    numberClick = function(e) {
        var button = (e.target) ? e.target : e.srcElement;
        if (operatorSet == true || currNumberCtl.innerHTML == '0') {
            setVal('');
            operatorSet = false;
        }
        setVal(currNumberCtl.innerHTML + button.innerHTML);
        setEquation(eqCtl.innerHTML + button.innerHTML);
    },

    calculate = function() {
        if (!operator || lastNumber == null) return;
        var currNumber = parseFloat(currNumberCtl.innerHTML),
            newVal = 0;
        //eval() would've made this a whole lot simpler
        //but didn't want to use it in favor of a more
        //"robust" set of methods to demo patterns
        switch (operator) {
        case '+':
            newVal = add(lastNumber, currNumber);
            break;
        case '-':
            newVal = subtract(lastNumber, currNumber);
            break;
        case '*':
            newVal = multiply(lastNumber, currNumber);
            break;
        case '/':
            newVal = divide(lastNumber, currNumber);
            break;
        }
        setVal(newVal);
        lastNumber = newVal;
    };

    return {
        init: init,
        numberClick: numberClick,
        setOperator: setOperator,
        clearNumbers: clearNumbers
    };
} ();


Functions that should be exposed publicly are defined in the return section of the Calculator object. In this example the init, numberClick, setOperator and clearNumbers functions are exposed by simply defining a JavaScript object literal that is returned when the main Calculator function is invoked. All of the other functions and variables defined in the Calculator object are private. JavaScript doesn’t support accessibility modifiers as C# or Java do but this pattern provides a nice way to emulate that type of functionality.

Looking through the code you may notice that a new function named init() was added that wasn’t in the previous examples. It’s responsible for accepting any initialization data that the Calculator object needs to work correctly. As soon as the page loads the Calculator object is created but init() needs to be called to pass two HTML elements that it interacts with. An example of calling init() is shown next:

 

window.onload = function () {
    var eqCtl = document.getElementById('eq');            
    var currNumberCtl = document.getElementById('currNumber');
    Calculator.init(eqCtl, currNumberCtl);
};


The Revealing Module Pattern is currently my favorite pattern out there for structuring JavaScript code mainly because it’s easy to use, very readable (which is important for maintenance), and provides a simple way to expose public members to consumers. What if we could combine this pattern with the Prototype Pattern though to get the benefits provided by prototyping? That’ll be the subject of my next post.

Update: The code shown here creates a single Calculator object. What if you need to create multiple instances of a given object in the same page though? This post details how to accomplish that.

Demos of all the patterns covered in this series can be downloaded below.

Download Code



Pluralsight Course - Structuring JavaScript Code in HTML5 Applications

If you're interested in additional information about structuring JavaScript code check out my Pluralsight course. Here's a sample from the course covering closures.

Demo - Working with Closures in JavaScript




Published Tuesday, August 02, 2011 4:20 PM by dwahlin

Comments

# Techniques, Strategies and Patterns for Structuring JavaScript Code - Dan Wahlin's WebLog

Pingback from  Techniques, Strategies and Patterns for Structuring JavaScript Code - Dan Wahlin's WebLog

# Techniques, Strategies and Patterns for Structuring JavaScript …

Pingback from  Techniques, Strategies and Patterns for Structuring JavaScript …

# re: Techniques, Strategies and Patterns for Structuring JavaScript Code–Revealing Module Pattern

Wednesday, August 03, 2011 6:38 AM by Scott Galloway

Lovely, been doing this for a while now as espoused by Javascript:The Good parts :)

# Dew Drop – August 3, 2011 | Alvin Ashcraft's Morning Dew

Wednesday, August 03, 2011 8:19 AM by Dew Drop – August 3, 2011 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop – August 3, 2011 | Alvin Ashcraft's Morning Dew

# re: Techniques, Strategies and Patterns for Structuring JavaScript Code–Revealing Module Pattern

Wednesday, August 03, 2011 11:24 AM by JB

Thanks for taking the time to write this series. This is great.

# re: Techniques, Strategies and Patterns for Structuring JavaScript Code–Revealing Module Pattern

Wednesday, August 03, 2011 12:07 PM by dwahlin
Elijah Manor had the following comment (added it for him since the comment system was giving problems):

Nice post! I love the Revealing Module Pattern ;)

A couple of things that you might consider are...

It is considered a best practice to only name constructors with a capital letter to convey to developers that they needs to "new" up a instance. So, I would lowercase the Calculator object above.

Here is a quote from Douglas Crockford... "Constructor functions which must be used with the new prefix should start with a capital letter. JavaScript issues neither a compile-time warning nor a run-time warning if a required new is omitted. Bad things can happen if new is not used, so the capitalization convention is the only defense we have." javascript.crockford.com/code.html

I tend to like a slightly different syntax of the same concept above. jsfiddle.net/.../presentation

Both syntaxes work, but I tend to find the one listed in the above fiddle to be a little more friendly.

# re: Techniques, Strategies and Patterns for Structuring JavaScript Code–Revealing Module Pattern

Wednesday, August 03, 2011 12:09 PM by Elijah Manor

Thanks Dan for adding the post for me... I'm not sure why it wasn't letting me do it ;)

# re: Techniques, Strategies and Patterns for Structuring JavaScript Code–Revealing Module Pattern

Wednesday, August 03, 2011 1:44 PM by Roger Martin

Can the Revealing Module Pattern pattern handle multiple instances on a page? With the prototype pattern, you just new up as many instances as you need. But - based on your example - the Revealing Module Pattern pattern looks more like a static class where you are limited to one instance on a page.

-Roger

# Techniques, Strategies and Patterns for Structuring JavaScript Code–Revealing Prototype Pattern

Sunday, August 07, 2011 12:56 PM by Dan Wahlin's WebLog

Using the JavaScript Revealing Prototype Pattern This is the 4th post in a series on techniques, strategies

# re: Techniques, Strategies and Patterns for Structuring JavaScript Code–Revealing Module Pattern

Sunday, August 07, 2011 1:13 PM by dwahlin

Roger: Since an object instance is created as the script is loaded it wouldn't work when you wanted multiple instances. However, you can remove the last two () and then do something like this to create multiple instances:

var myCalc = Calculator();

myCalc.init(val,val2);

Dan

# Building the Account at a Glance HTML5/jQuery Application

Tuesday, August 16, 2011 12:03 AM by Dan Wahlin's WebLog

As Web technologies continue to evolve developers are required to learn new technologies in order to

# re: Revealing Module Pattern - Techniques, Strategies and Patterns for Structuring JavaScript Code

Wednesday, August 31, 2011 12:52 PM by Keith Chadwick

While defining a variable as name = function(){} does imply a var statement and the scope is within the base function it is still good habit to put a var [name]= function(){} as it is more explicit and allows for better readability.  Not to mention some day in the future where not having the var declaration could cause collisions with global scoped objects.

# re: Revealing Module Pattern - Techniques, Strategies and Patterns for Structuring JavaScript Code

Wednesday, August 31, 2011 2:42 PM by dwahlin

Keith: Thanks for commenting. All of the variables are separated with a comma allowing var to be used just once. As a result, they're not in the global scope even if they were moved outside of the containing function. It's a common pattern a lot of JavaScript developers are doing now although some people don't like it since at first glance makes some variables look like they're in the global scope - not the case here though.

Some people prefer to explicitly put var in front of each definition, but by separating the vars with commas you can eliminate the need for that and keep some of the var clutter out of a script. As long as commas are used (as opposed to semi-colons) it all boils down to the same thing. At that point it's just personal preference. I cover that general topic at the bottom of the first post on this series: weblogs.asp.net/.../techniques-strategies-and-patterns-for-structuring-javascript-code.aspx

# Creating Multiple JavaScript Objects when using the Revealing Module Pattern

Tuesday, September 06, 2011 12:02 AM by Dan Wahlin's WebLog

In my previous series on Techniques, Strategies and Patterns for Structuring JavaScript Code I discussed

# Techniques, Strategies and Patterns for Structuring JavaScript Code

Tuesday, November 01, 2011 1:26 AM by Dan Wahlin's WebLog

JavaScript has come a long way since the mid-90s when I first started working with it in Netscape 3 and

# Video: Structuring JavaScript with the Revealing Module Pattern

Monday, February 27, 2012 2:16 AM by Dan Wahlin's WebLog

This sample video from Pluralsight’s Structuring JavaScript Code course provides an introduction to the

# Prepare your webapp: CSS and Javascript concatenation and minification | Me and myself

Pingback from  Prepare your webapp: CSS and Javascript concatenation and minification | Me and myself

# SPA 6 – SPA Basics – Separating the Ravioli – Code Camper | Greg Kai on the Fly

Pingback from  SPA 6 – SPA Basics – Separating the Ravioli – Code Camper | Greg Kai on the Fly