benpink
benpink

Reputation: 45

Does anyone recognise this javascript design pattern?

This is a js pattern I've found myself using and tweaking over the years.

The thing is, I fell into it after some experimentation and I'm keen to know whether this type of pattern has a name. I've browsed through a lot of design patterns but not found anything similar (or as simple, especially for modular type patterns).

var FOO = (function ($) {
    var privateFuncA = function() {
        ...
    },        
    privateFuncB = function() {
        ...
    },
    self = {
        init: function() {
            privateFuncA(); // Call a private func
            self.publicFunc(); // Call a public func
        },
        publicFunc: function() {
            ...
        }
    };
    return self;
}(jQuery));

$(function () {
    // Initialise FOO
    FOO.init();
});

Idea is to keep everything namespaced and allows for pseudo-public/private funcs.

If I need to go modular I'll extend the base FOO object:

// Extend FOO object
FOO.Bar = (function ($) {
    var privateFunc = function() {
        ...
    },
    self = {
        publicFunc: function() {
            ...
        }
    };
    return self;
}(jQuery));

If you want to call publicFunc in the extended object from outside you can:

FOO.Bar.publicFunc()

Does anyone know if this type of pattern has a name or whether there's any known issues with such a design?

Upvotes: 3

Views: 103

Answers (1)

LetterEh
LetterEh

Reputation: 26696

Sure. It's just an extension of Christian Hielmann's "Revealing Module" pattern, which was itself an extension of Douglas Crockford's Module pattern.

In a lot of my examples here on SO, I'll use something very similar, except replacing self with public_interface, to try to make it more obvious as to what is public, private or private-static.

var built_module = (function () {

    var private_data = "",
        private_method = function () { /* ... */ },

        public_interface = {
            public_method : function () { /* ... */ },
            public_data
        };

    return public_interface;

}());

and as a constructor:

var built_constructor = (function (env_params) {

    var static_data = "",
        static_method = function () { /* ... */ },

        public_constructor = function (params) {
            var private_data = "",
                private_method = function (params) { /* ... */ },

                public_interface = {
                    public_method : function () { /* ... */ },
                    public_data
                };

            return public_interface;
        };

    return public_constructor;
}(envArgs));


var myInstance = built_constructor(myArgs);

The "static" data/properties are in an outer-closure, so all of the vars/functions within the inner-closure have access to them, while the "static" methods have no access to any instance-methods/data, without passing arguments into the function.

You can extend it in any way from here -- removing the return value, and instead assigning the public_interface as a property of an object, or window by default (for namespacing).

Upvotes: 3

Related Questions