0

It's my understanding the Javascript Module Pattern simulates classes found in class-based languages, but I haven't been able to find an example of an object being instantiated using this pattern. In Java, classes are instantiated like this:

var myClassInstance = new MyClass();

All the Module Pattern tutorials I've seen explain the creation of a module with this basic syntax:

var MyModule = (function(){
    var privateMember = 'foo';

    function publicMember() {
    }        

    return {
        publicMember: publicMember
    }
}());
  1. How would I then create a new instance of MyModule in this example?
  2. Are modules meant to be instantiated?
  3. What's the proper way to instantiate an object using the Module Pattern?
Pup
  • 10,236
  • 6
  • 45
  • 66
  • you might want to have a look at http://stackoverflow.com/a/9321429/1048572 or http://stackoverflow.com/a/15437040/1048572 – Bergi Sep 07 '16 at 00:16

1 Answers1

3

How would I then create a new instance of MyModule in this example?

In your example you cannot create an instance of your module because it is a plain object.

Are modules meant to be instantiated?

Most aren't meant to be but it's up to you if your module should be instantiated first in order to use it.

What's the proper way to instantiate an object using the Module Pattern?

Classes can be 'emulated' in javascript like this:

var MyClass = (function(){
    function MyClass() {
    }

    var privateMethod = function() {};
    MyClass.staticMethod = function() {};
    MyClass.prototype.instanceMethod = function() {};

    return MyClass;
}());

var classInstance = new MyClass();

And modules or namespaces like this, just as in your example:

var MyModule = (function(){
    var MyClass = (function(){
        function MyClass() {
        }

        var privateMethod = function() {};
        MyClass.staticMethod = function() {};
        MyClass.prototype.instanceMethod = function() {};

        return MyClass;
    }());            

    return {
        MyClass: MyClass
    };
}());

var classInstance = new MyModule.MyClass();

These are very simple examples but this pattern can be very complex. Like this other example of a module that you must instantiate in order to use its classes:

var MyModule = (function() {

  /** Module constructor */
  function MyModule(arg0, arg1) {

    this.MyClass = (function() {

      /** Class constructor */
      function MyClass() {
        this.publicArg0 = arg0;
        this.publicArg1 = arg1;
      }

      var privateMethod = function() {};
      MyClass.staticMethod = function() {};
      MyClass.prototype.instanceMethod = function() {};

      return MyClass;
    }());

  };

  return MyModule;
}());

var moduleInstance = new MyModule('#some', 1324);
var classInstance = new moduleInstance.MyClass();

console.log(classInstance.publicArg0) // "#some"
console.log(classInstance.publicArg1) // "1324"
Santiago Hernández
  • 5,438
  • 2
  • 26
  • 34
  • 1
    That last example seems to be an antipattern. "Instantiating" a module would imply that you could have multiple instances of it - yet your variables are static, and you must call `new MyModule` exactly once. Better make it a singleton object and give it an `.init(…)` method. – Bergi Sep 07 '16 at 00:06
  • I have to admit I prefer factories over constructors when there's a) no instance state and b) no inherited properties to be shared, but +1 nonetheless – Bergi Sep 07 '16 at 00:19
  • @Bergi I think a singleton would make the code a tiny bit longer. Actually, the way it is now looks dead simple, although it isn't, e.g. one can be confused on how `this`'s value changes if it is inside of which function. – Santiago Hernández Sep 07 '16 at 00:32