<< 20 October 2011 | Home | 22 October 2011 >>

The JavaScript Module Pattern - adding namespace

The Module Pattern has as added benefit of allowing you to add namespace to classes. The below extends the previous example to make the class COM.LEKKIMWORLD.ModuleAbc. Very cool in my eyes and reduces the chance for name collisions much like with Dojo classes.

// Create a COM namespace
var COM = (function() {
  return {};
}());

// Create a LEKKIMWORLD namespace
COM.LEKKIMWORLD = (function() {
  return {};
}());

// Add a class called ModuleAbc to the COM.LEKKIMWORLD namespace
COM.LEKKIMWORLD.ModuleAbc = (function(secret) {
  // the object we're incapsulating
  var OBJ = {};

  // private variables (these are truely private and 
  // cannot be accessed from the outside)
  var secret = "my secret is: " 

  // my property
  OBJ.myproperty = "my property value";

  // echo method
  OBJ.echo = function(v) {
    return "Echo: " + v;
  };
  
  // return the object
  return OBJ;
  
});

The JavaScript Module Pattern

If you are like me you like object oriented programming and you try to encapsulate the functionality to the best of your ability. And that goes for JavaScript as well of course. JavaScript pose an interesting problem though as JavaScript objects are as opaque as air that is you can see right through it.

Normally an object in JavaScript - whether declared though dojo.declare or function/json isn't able to hide it's member variables at all. You can try with "this." or using _neverUser naming but fundamentally the "private" variables of a JavaScript class are available from the outside. Consider the below examples:

// enter the dojo
var DojoAbc = dojo.declare(null, {
  constructor: function(secret) {
    this.mysecret = secret;
  },
  myproperty: "my property value", 
  echo: function(v) {
    return "Echo: " + v;
  }
});
var myDojoAbc = 
   new DojoAbc("my little secret");
alert(myDojoAbc.echo(new Date()));
alert(myDojoAbc.myproperty);
alert(myDojoAbc.mysecret);

// plain ol' JavaScript
var PlainAbc = function(secret) {
  this.mysecret = secret;
  this.myproperty = "my property value";
  this.echo = function(v) {
    return "Echo: " + v;
  }
};
var myPlainAbc = 
   new PlainAbc("my little secret");
alert(myPlainAbc.echo(new Date()));
alert(myPlainAbc.myproperty);
alert(myPlainAbc.mysecret);
In both examples the "mysecret" variable is accessible although I didn't mean it to. There is no way in the above example to make the mysecret-variable invisible to the outside. That is a user of your class can access it and see it using a JavaScript debugging such as Firebug.

Bummer I thought. What then? How do I do it? Well I'm glad you asked as there is a way. It's called the Module Pattern. Let me show you but let me also warn you - it is a little conveluted to look at.

The below code starts by creates a class like above but nothing besides the myproperty-property and the echo-method are available (even in Firebug) from the outside. So the last alert will actually say "undefined" as mysecret is available to the outside. It's super cool and it's the way I'm going to do my objects from now on.

var ModuleAbc = (function(secret) {
  // the object we're incapsulating
  var OBJ = {};

  // private variables (these are 
  // truely private and cannot be 
  // accessed from the outside)
  var secret = "my secret is: " 

  // my property
  OBJ.myproperty = "my property value";

  // echo method
  OBJ.echo = function(v) {
    return "Echo: " + v;
  };
  
  // return the object
  return OBJ;
  
});

// use case
var myModuleAbc = 
   new ModuleAbc("my little secret");
alert(myModuleAbc.echo(new Date()));
alert(myModuleAbc.myproperty);
alert(myModuleAbc.mysecret);

More information about the pattern incl. composition, inheritance etc. can be found on the the Adequately Good blog in the JavaScript Module Pattern: In-Depth post.

Have an excellent Friday.