Namespacing Your JavaScript Objects
Problem
You want to encapsulate your data and functions in such a way as to prevent clashes
with other libraries.
Solution
Use an object literal, what I call a one-off object, to implement the JavaScript version of
namespacing. An example is the following
var jscbObject = {
// return element
getElem : function (identifier) {
return document.getElementById(identifier);
},
stripslashes : function(str) {
return str.replace(/\\/g, '');
},
removeAngleBrackets: function(str) {
return str.replace(
/g,'>');
}
};
var sample = "
testing\changes
";
var result = jscbObject.stripslashes(sample);
result = jscbObject.removeAngleBrackets(result);
console.log(result); //<div>testingchanges</div>
As mentioned elsewhere in this book, all built-in objects in JavaScript have a literal representation in addition to their more formal object representation. For instance, an Array can be created as follows:
var newArray = new Array('one','two','three');
or using the array literal notation:
var newArray = ['one','two','three'];
The same is true for objects. The notation for object literals is pairs of property names and associated values, separated by commas, and wrapped in curly brackets:
var newObj = {
prop1 : "value",
prop2 : function() { ... },
...
};
The property/value pairs are separated by colons. The properties can be scalar data values or they can be functions. The object members can then be accessed using the object dot-notation:
var tmp = newObj.prop2();
or:
var val = newObj.prop1 * 20;
or:
getElem("result").innerHTML=result;
Using an object literal, we can wrap all of our library’s functionality in such a way that the functions and variables we need aren’t individually in the global space. The only global object is the actual object literal, and if we use a name that incorporates functionality, group, purpose, author, and so on, in a unique manner, we effectively namespace the functionality, preventing name clashes with other libraries.
Advanced
I use the term one-off with the object literal rather than the more commonly known singleton because, technically, the object literal doesn’t fit the singleton pattern. A singleton pattern is one where only one instance of an object can be created. We can say this is true of our object literal, but there’s one big difference: a singleton can be instantiated at a specific time rather than exist as a static construct, which is what the solution defines.
var mySingleton = (function () {
// Instance stores a reference to the Singleton
var instance;
function init() {
// Singleton
// Private methods and variables
function privateMethod(){
console.log( "I am private" );
}
var privateVariable = "Im also private";
var privateRandomNumber = Math.random();
return {
// Public methods and variables
publicMethod: function () {
console.log( "The public can see me!" );
},
publicProperty: "I am also public",
getRandomNumber: function() {
return privateRandomNumber;
}
};
};
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: function () {
if ( !instance ) {
instance = init();
}
return instance;
}
};
})();
singleA = mySingleton.getInstance();
var singleB = mySingleton.getInstance();
console.log( singleA.getRandomNumber() === singleB.getRandomNumber() );
The singleton uses an Immediately-Invoked Function Expression (IIFE) to wrap the object, which immediately returns an instance of the object. But not just any instance —if an instance already exists, it’s returned rather than a new instance.
The latter is demonstrated by the object’s getRandomNumber() function, which returns a random number that is generated when the object is created, and returns the same random number regardless of which “instance” is accessed.

No comments:
Post a Comment