Javascript Module Pattern / Prototype Pattern : can't figure out this code

I trying to create a simple google maps plugin. I’m following a tutorial but i can’t figure out this block of code. Anyone could explain me this code ?

(function(window, google) {

   var Mapster = (function() {
       function Mapster(element, opts) {
           this.gMap = new google.maps.Map(element,opts);
       }

       Mapster.prototype = {
           zoom: function(level) {
               //some code here
           }
       };
   
       return Mapster;
   }());

  Mapster.create = function(element, opts) {
      return new Mapster(element, opts);
 };

 window.Mapster = Mapster;

}(window, google));

The first part defines the Mapster variable as a function with a prototype (I don’t see the necessity of the Module Pattern for the shown bit of code, but this kind of encapsulation doesn’t hurt either).

After that a factory function is created on the Master variable/function (in class-based languages that would be a static function) and then it’s made available as an explicit global.

function Mapster(element, opts) {
           this.gMap = new google.maps.Map(element,opts);
       }

This constructor function adds a new Map object as a property for every new Mapster object created using new Mapster, while also initialising the new Map property/object using element and opts arguments.

Mapster.prototype = {
           zoom: function(level) {
               //some code here
           }
       };

Every new Mapster object will inherit from the Mapster.prototype, so adding to the prototype is the way to go for having one set of properties shared among many Mapster objects as opposed to every Mapster object having its own copy of said properties.

Mapster.create = function(element, opts) {
      return new Mapster(element, opts);
 };

It follows the Object.create pattern to create new objects.

window.Mapster = Mapster;

Replaces any other Mapster properties the window global object may have with the Mapster created above. Not really a good practice.

2 Likes

I’d like to know why this is a good thing. If we had a this.zoom=somefunc() in the first Mapster, wouldn’t all other Mapsters have it anyway, just as they have a gmap (through looking it up)?

but each Mapster object would have its own copy as opposed to sharing the function from the prototype. that is, it uses more memory than necessary.

besides that, this.gMap is not a function (didn’t read the google maps API, though. but I doubt it is),

You are right but we’d have to be using Object.create instead of new and we’d have to provide a init object or a init function instead of the current constructor. Instead of building the prototype property object we would be using an object as a prototype for another.

var Mapster = {};

Mapster.zoom = function() {
  console.log(this.gMap);
};

var m = Object.create(Mapster, {gMap: {value: 'm'}});

m.zoom(); // 'm'

Mapster.zoom = 'changed';
m.zoom; // 'changed'
m.gMap; // 'm'

The big difference is that with using a constructor function, Mapster is a function the same way native Array is, m constructed with new Mapster is recognizable as a Mapster the same way ['m'] is recognizable as an Array. With using {} for Mapster and Object.create for building m, both are just Objects. Is the first one good or the second one good, that’s a either a choice or an alternative, but looking at the available JavaScript docs, they tend to list Something.prototype.SomethingElse.

We can always do this:

var Mapster = function(arg) {...};
Mapster.prototype = Object.create(Higher.prototype)

to avoid using new and get something from both worlds: constructor functions and prototype objects for the prototype property object.