What is the benefit of the Javascript Module Pattern?

I have been doing research to come up with a standardized Javascript coding style for my team. Most resources now recommend the "Module" pattern that involves closures, such as this:

var Module = function() { 

    someMethod = function() { /* ... */ };

    return { 
        someMethod: someMethod
    };

}();

and invoke it like Module.someMethod(); . This approach seems to only work with methods that would be static in a traditional OOP context, for example repository classes to fetch/save data, service layers to make outside requests, and the like. Unless I missed something, the module pattern isn't intended to be used with data classes (think DTOs) that would typically need to be passed to/from the service methods to the UI glue code.

A common benefit I see cited is that you can have true private methods and fields in Javascript with the module pattern, but this can also be achieved along with being able to have static or instance methods with the "classical" Javascript style similar to this:

myClass = function(param) { 
    // this is completely public
    this.publicProperty = 'Foo';

    // this is completely private
    var privateProp = param;

    // this function can access the private fields
    // AND can be called publicly; best of both?
    this.someMethod = function() { 
        return privateProp;
    };

    // this function is private.  FOR INTERNAL USE ONLY
    function privateMethod() { 
        /* ... */
    };
}

// this method is static and doesn't require an instance
myClass.staticMethod = function() { /* ... */ };

// this method requires an instance and is the "public API"
myClass.prototype.instanceMethod = function() { /* ... */ };

So I guess my question is what makes the Module Pattern better than the traditional style? It's a bit cleaner, but that seems to be the only benefit that is immediately apparent; in fact, the traditional style seems to offer the ability to provide real encapsulation (similar to true OOP languages like Java or C#) instead of simply returning a collection of static-only methods.

Is there something I'm missing?


The module pattern above is pointless. All you are doing is using one closure to return a constructor with prototype. You could have achieved the same with:

function Module() {};
Module.prototype.whatever = function() {};

var m = new Module();
m.whatever();

In fact you would have saved one object (the closure) from being created, with the same output.

My other beef with the module pattern is it if you are using it for private encapsulation, you can only use it easily with singletons and not concrete classes. To create concrete classes with private data you end up wrapping two closers, which gets ugly. I also agree that being able to debug the underscore pseudo-private properties is a lot easier when they are visible. The whole notion of "what if someone uses your class incorrectly" is never justified. Make a clean public API, document it, and if people don't follow it correctly, then you have a poor programmer in your team. The amount of effort required in Javascript to hide variables (which can be discovered with eval in Firefox) is not worth the typical use of JS, even for medium to large projects. People don't snoop around your objects to learn them, they read your docs. If your docs are good (example using JSDoc) then they will stick to it, just like we use every 3rd party library we need. We don't "tamper" with jQuery or YUI, we just trust and use the public API without caring too much how or what it uses underneath.


Another benefit you forgot to mention to the module pattern, is that it promotes less clutter in the global namespace, ie, what people refer to when they say "don't pollute the global namespace". Sure you can do that in your classical approach, but it seems creating objects outside of anonymous functions would lend more easily to creating those objects in the global namespace.

In other words, the module pattern promotes self contained code. A module will typically push one object onto the global namespace, and all interaction with the module goes through this object. It's like a "main" method.

Less clutter in the global namespace is good, because it reduces the chances of collisions with other frameworks and javascript code.


Module Pattern can be used to create prototypes as well see:

var Module = function() { 
  function Module() {};
  Module.prototype.whatever = function() {};
  return Module
}();
var m = new Module();
m.whatever();

As the other poster said the clean global namespace is the reason for it. Another way to achieve this however is to use the AMD pattern, which also solves other issues like dependency management. It also wraps everything in a closure of sorts. Here's a great Introduction to AMD which stands for Asynchronous Module Definition.

I also recommend reading JavaScript Patterns as it thoroughly covers the reasons for various module patterns.

链接地址: http://www.djcxy.com/p/59464.html

上一篇: 建议像谷歌与Postgresql卦和全文搜索

下一篇: Javascript模块模式有什么好处?