Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding how JS Module Pattern works

I'm trying to understand js module patterns in use with jQuery. I've edited this a couple of times and will try to end up with a good practice for my skill level (a couple of months fresh on jquery).

There's no direct question in this post. I'm more aiming for feedback and inputs on how to properly use the module pattern (together with jquery) in a large scale website.

Update: I've added a bunch of examples in order to get an overview of all ways of writing things, and try to cover any pitfalls..

/* 
Not all browsers works with console.log, so we want to make sure that
console.log is defined. This defines the consol.log and send the messages
into an alert.
*/
if(!window.console) console = {
  log: function(s) { 
    alert(s); // alert since we dont have the firebug console
  }
};

// Check if namespace is defined
if (typeof (CompanyName) === 'undefined') {
    CompanyName = {};
}

// Or if AppName under CompanyName...

if (typeof (CompanyName.AppName) === 'undefined') {
    CompanyName.AppName = {};
}

// Our namespace
CompanyName.AppName = (function ($) {

    // CHAINING
    var _first = function () {
        // Important to always start with "var"
    },

    _second = function () {
        // Chained (  ...},  ) so it doesnt need "var"
    },

    _third = "Just a var", // Variables just ends with ,

    _four = "Another var"; // Closing the chain with ;

    var _anotherFirst = function () {
        // Previous chain of var's was ended with ; so this var needed "var" in order to start.
    };

    g_globalVar = "I'm free!"; // When starting a var without "var", it becomes global.

    g_globalMethod = function () { 
        alert("I'm free too!"); // Global method.
    };

    g_chainedGlobalVarOne = "We are free!",
    g_chainedGlobalVarTwo = "We are free!";

    // Private Variables
    var _privateVar = "privateVar: accessed from within AppLaunch.Admin namespace";

    // Private Methods
    var _privateMethod = function () {
       log("privateMethod: accessed only from within AppLaunch.Admin");
    }; // Last variable in a chain must always end with ; before the return {}

    function log() {
        if (window.console && window.console.log)
            window.console.log('[AppName] ' + Array.prototype.join.call(arguments, ' '));
    };

    return {
        init: function () {

            // Calling private
            _privateMethod();

            // Calling Public
            this.myPublicMethod();

            // Also Calling Public
            CompanyName.AppName.myPublicMethod();

            // Calling Other namespace's Public Method (when exists)
            CompanyName.OtherNamespace.externalPublicMethod(); 
        },

        // Public
        myPublicMethod: function() {
            log("myPublicMethod");
        },
        // In a View (MVC), I could have a page called myPage where I want to init
        // some particular functions. myPage can be called just like init. 
        myPage: function() { 
            _second();
            _third();
        }

    }
})(jQuery); 

// Initialize
jQuery().ready(function() {
    CompanyName.AppName.init()
    CompanyName.AppName.myPublicMethod();
});  

Trying to understand what's happening (Feel free to provide corrections or better explanations):

Company.AppName = (function ($) { ...

Here the namespace Company.AppName is created. I set ($) inside so I can use the $ without it conflicting with any other libraries that might use $.

})(jQuery); 

As far as I know, the methods and variables are returned to the namespace here ...})(); and by adding jQuery inside () it'll tell it that the $ means jQuery.

Initializing

I'm not sure what's best practice here, but I'll add what I know so far.

Initializing within js file:

jQuery(function() { 
    AppLaunch.Admin.init();
});

Initializing from a file:

<script type="text/javascript">
// Shorthand for jQuery(document).ready(function() { ... }

jQuery(function($) { 
    AppLaunch.Admin.init($('#someSelector'));     
});
</script>
like image 403
olemarius Avatar asked Nov 30 '10 08:11

olemarius


People also ask

What is module pattern in JS?

The Module Pattern is one of the most common design patterns used in JavaScript and for good reason. The module pattern is easy to use and creates encapsulation of our code. Modules are commonly used as singleton style objects where only one instance exists. The Module Pattern is great for services and testing/TDD.

How do JavaScript modules work?

A module in JavaScript is just a file containing related code. In JavaScript, we use the import and export keywords to share and receive functionalities respectively across different modules. The export keyword is used to make a variable, function, class or object accessible to other modules.

What is the main advantage of using the module pattern in JavaScript?

The Javascript module pattern enables the implementation of the closure principle providing the control of privacy in your methods so that third party applications or modules cannot access data in variables or overwrite it.

What is modular design pattern?

In software engineering, the module pattern is a design pattern used to implement the concept of software modules, defined by modular programming, in a programming language with incomplete direct support for the concept.


1 Answers

There are many places that will give you an in depth explanation of the module pattern; jQuery's usage of it is pretty standard.

This is just one of the many module pattern explanations out there.

like image 170
El Yobo Avatar answered Oct 11 '22 12:10

El Yobo