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.
I use this pattern a lot, I find it very accessible since it’s really pretty self-explanatory once you figure out how function scope works in JavaScript. There is also a great section about this in the mini-book by Addy Osmani over at http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript
LikeLike