OOP in JavaScript - Part 2: Static classes and Singleton
15. September 2009
comments feed
After I've covered normal classes in Part 1 of the series, the second part will focus on static classes and singletons. As before basic OOP and JavaScript knowledge is needed.
Generally writing and using static classes is monstly the same as normal classes. The difference is that you don't need to instantiate the object with new and you can't use prototyping nor this, since everything is in static context. One useful implementation for static classes is the Registry Design Pattern. First off we create the class with a property to store the registry values in afterwards:
function Registry()
{
}
Registry._data = {};
Right now, I can't really do a lot with this class, that's why I'll create a static method that allows me to set key-value-combinations:
Registry.set = function(key, value) {
Registry._data[key] = value;
}
Now I'm able to register stuff in the registry. Since I don't need an instance of the class I can call my method directly:
Registry.set('userIsAuthorized', false);
I'll leave out the getter you'd still need for a useful registry.
If you want to prevent anyone from writing new Registry() you only have to throw an exception in the constructor:
function Registry()
{
throw('You cannot instantiate Registry');
}
Maybe for some reason you wanna use Registry as a singleton. In that case you have to combine normal class methods and properties with static ones. You write the Registry as a normal class and implement one static property instance and one static method getInstance. The Registry class would then look like this:
function Registry()
{
}
Registry.instance = null;
Registry.getInstance = function() {
if (Registry.instance === null) {
Registry.instance = new Registry();
}
return Registry.instance;
}
Registry.prototype._data = {};
Registry.prototype.set = function(key, value) {
this._data[key] = value;
}
Since JavaScript doesn't have access modifiers like private, public or protected I had to remove the exception from the constructor. You could do it with a randomly generated token passed to the constructor, but this method is not bulletproof like any other I can think of.
In part 3 (that'll come later this week) I will write about extending classes.
3 comments
Matthew Maxwell
15.09.2009, 18:04 o'clock
Just realized that the format of that is ugly and I forgot a semicolon after var _data = {}; Sorry about that :(
Dominik Jungowski
16.09.2009, 18:11 o'clock
Yupp, thanks. Paul already showed me that way in the comments for OOP in JS Part 1
recent posts
Matthew Maxwell
15.09.2009, 18:02 o'clock
You can do private-like variables in JavaScript:
function Registry() {
var _data = {}
var that = this; // scope resolution for chaining
this.set = function (key, value) {
_data[key] = value;
return that; // returns our Registry object
};
this.get = function (key) {
return _data[key];
};
}
Now, you could instantiate a new Registry:
var reg = new Registry();
reg._data // undefined
reg.set("userIsAuthorized", false); // returns reg, so we could chain with other commands
reg.get("userIsAuthorized") // false
reg._data // undefined
If we view reg, _data will not be seen, and is therefore a "private" variable in the JavaScript class.