lucamilan
6/10/2012 - 12:11 PM

Explain difference between revealing module pattern and using a constructor as namespace

Explain difference between revealing module pattern and using a constructor as namespace

//create our "FOO" namespace
window.FOO = window.FOO || {};


FOO.app1 = {

    bar : 'foo',

    init : function(){
        //this wont work as expected since timeout changes scope
        // the same would happen if it was an event handler like
        // "onclick", "onload", etc..
        setTimeout(this.logBar, 15);
    },

    logBar : function(){
        console.log('app1: '+ this.bar);
    }

};

FOO.app1.init();



// I've seen some people using this pattern in a couple places
// It has the same output as using a literal object (since "new function" 
// returns a new object).

FOO.app2 = new function() {

    this.bar = 'foo';

    this.init = function() {
        //this wont work as expected since timeout changes scope
        // the same would happen if it was an event handler like
        // "onclick", "onload", etc..
        setTimeout(this.logBar, 15);
    };

    this.logBar = function(){
        console.log('app2: '+ this.bar);
    };
}

FOO.app2.init();




FOO.app3 = (function() {

    //properties that should be exported, we only add stuff to this object if
    //it needs to be public and we reference all functions internally as if it
    //wasn't part of this object

    var app = {
        bar : 'foo'
    };

    function init() {
        //work as expected
        setTimeout(logBar, 15);
    }

    function logBar(){
        console.log('app3: '+ app.bar);
    }

    // Export API
    // ----------
    // we only do it later so we avoid using the "this" keyword or "app.method()"
    // through our module code, it helps to reduce scope issues and keeps code 
    // organized. It's also easier to spot what is public and what isn't.
    //
    // If we didn't needed to expose "bar" we would just return
    // a plain object like:
    // {
    //   init : init,
    //   logBar : logBar
    // }

    app.init = init;
    app.logBar = logBar;

    return app;

}());

FOO.app3.init();