Javascript - Revealing Module Pattern

javascript

var myRevealingModule = (function () {
    var privateVar = "Ben Cherry",
        publicVar = "Hey there!";

    function privateFunction() {
        console.log( "Name:" + privateVar );
    }

    function publicSetName( strName ) {
        privateVar = strName;
    }

    function publicGetName() {
        privateFunction();
    }

    // Reveal public pointers to
    // private functions and properties
    return {
        setName: publicSetName,
        greeting: publicVar,
        getName: publicGetName
    };
})();
NS.App = (function () {
    // Initialize the application
    var init = function () {
        NS.Utils.log('Application initialized...');
    };

    // Return the public facing methods for the App
    return {
        init: init
    };
}());

NS.App.init();

Above, an App function is defined within the NS object. Inside, a function variable for init is defined, and returned as an anonymous object literal. Notice that, at the end, there’s that extra set of parenthesis: }());. This forces the NS.App function to automatically execute and return. Now, you can call NS.App.init() to initialize your app.

The anonymous function above is a best practice in JavaScript, and is referred to as a Self-Executing Anonymous Function. Because functions in JavaScript have their own scope – i.e. variables defined inside of functions are not available outside of them – this makes anonymous functions useful in multiple ways.

// Wrap your code in a SEAF
(function (global) {

    // Now any variables you declare in here are unavailable outside.
    var somethingPrivate = 'you cant get to me!';

    global.somethingPublic = 'but you can however get to me!';

}(window));

console.log(window.somethingPublic); // This works...
console.log(somethingPrivate); // Error

In this example, because this function is automatically executed, you can pass the window in to the executing part }(window));, and it will be made available as global inside of the anonymous funtion. This practice limits the global variables on the window object, and will assist in preventing naming collisions.

Now, you can start using SEAF’s in other areas of your application to make the code feel more modular.

(function ($) {
    var welcomeMessage = 'Welcome to this application!'

    NS.Views.WelcomeScreen = function () {
        this.welcome = $('#welcome');
    };

    NS.Views.WelcomeScreen.prototype = {
        showWelcome: function () {
            this.welcome.html(welcomeMessage)
                .show();
        }
    };
}(jQuery));

$(function () {
    NS.App.init();
});

// Modify the App.init above
var init = function () {
    NS.Utils.log('Application initialized...');
    this.welcome = new NS.Views.WelcomeScreen();
    this.welcome.showWelcome();
};

Firstly, jQuery is passed as an argument to the anonymous function. This ensures that the $ is actually jQuery inside of the anonymous function. Next, there’s a private variable, called welcomeMessage, and a function is assigned to NS.Views.WelcomeScreen. Inside this function, this.welcome is assigned to a jQuery DOM selector. This caches the selector inside the welcomeScreen, so that jQuery doesn’t have to query the DOM for it more than once.

DOM queries can be memory intensive, so please ensure that you cache them as much as possible.

Next, we wrap the App init within $(function(){});, which is the same thing as doing $(document).ready().

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License