Single Global JavaScript Object Namespace

In some development environments, you don't know in advance what JavaScript Code will end up on a page. This can lead to an accidental variable naming conflict between your JavaScript code and the other JavaScript code that ends up on the page. I run into this problem frequently when developing JS code for Joomla Extensions. Here is a way to have only a single Object in the global scope of the JS Script.

If you are familiar with the OOP style JavaScript (prototypes), then the code should look familiar. The problem I have with the syntax of creating object instances is its verbosity. If you only need to use an instance once, then you can use something like:

(new GlobalObj()).getX(); // call the method getX
However, if you want to reuse the instance in other parts of your code, you have to keep a reference of that instance using a variable.
var GlobalInstance = new GlobalObj();
GlobalInstance.x = 'hi'; // set the property x
GlobalInstance.getX(); // call the method getX

This becomes very verbose quickly if you have a lot of references to instances of an Object. So here is a solution:

GlobalObj = function(index) {
	if (this instanceof GlobalObj) {
		GlobalObj.staticInstances[index || null] = this;
	} else {
		return GlobalObj.staticInstances[index || null] || new GlobalObj();
	}
};
GlobalObj.staticInstances = {};
Here we have the single JS object GlobalObj. This Object will both handle the Construction of the Instances of GlobalObj (itself) and the access of the methods and properties.

Say you add the method getX() to the Object's prototype.

GlobalObj.prototype.x = null;
GlobalObj.prototype.getX = function() {
	return this.x;
}
The method returns the value of property "x" of the GlobalObj Object Instance.

Here's how you construct an instance of GlobalObj

new GlobalObj();
Note that you don't have to assign the instance to a variable. GlobalObj will assign its own instance to its static property staticInstances for you.

Say you want to assign a value to the property "x" of your Object's Instance.

GlobalObj().x = 'hi';
Now you can access this property:
var x = GlobalObj().getX();
alert(x);
Notice two things:
  • The only global object is GlobalObj.
  • GlobalObj is a static function that returns its Instance.

Tradition Global Namespace

The same code would require at least two objects in JavaScript's Global Namespace if you were to write this the traditional way.
// global Object
GlobalObj = function() {
	
};
GlobalObj.prototype.x = null;
GlobalObj.prototype.getX = function() {
	return this.x;
}

// global Object Instance
GlobalObjectInstance = new GlobalObj();
GlobalObjectInstance.x = 'hi';
GlobalObjectInstance.getX();
Note that you have two Global Objects: GlobalObj and GlobalObjectInstance.

What the methodology mentioned does is save each Instance into a static property of the Static Object or constructor of the Instance.

This is what it would look like if you wrote it out yourself.

// global Object
GlobalObj = function() {
	
};
GlobalObj.prototype.x = null;
GlobalObj.prototype.getX = function() {
	return this.x;
}

// global Object Instance
GlobalObj.staticInstance = new GlobalObj();
GlobalObj.staticInstance.x = 'hi';
GlobalObj.staticInstance.getX();

The convenience of having this done automatically can be seen when you have to create multiple instances of your global object:

// Object in global namespace
GlobalObj = function(index) {
	if (this instanceof GlobalObj) {
		GlobalObj.staticInstances[index || null] = this;
	} else {
		return GlobalObj.staticInstances[index || null] || new GlobalObj();
	}
};
GlobalObj.staticInstances = {};

// custom methods
GlobalObj.prototype.x = null;
GlobalObj.prototype.getX = function() {
	return this.x;
}

// note: instances are created automatically when you assign a property

// first instance uses default instance
GlobalObj().x = 'hi';
alert(GlobalObj().getX());

// second instance uses instance indexed with 'bye'
GlobalObj('bye').x = 'bye';
alert(GlobalObj('bye').getX());
Not only is this much more convenient for the programmer, it is more readable and much shorter in syntax.

Updates

Use of instanceof keyword instead of testing this against window.

GlobalObj = function(index) {
	if (this instanceof GlobalObj) {
		GlobalObj.staticInstances[index || null] = this;
	} else {
		return GlobalObj.staticInstances[index || null] || new GlobalObj();
	}

 

Joomla Downloads

DownloadsDownload our free Joomla! Components, Modules and Plugins.