Singleton

The singleton pattern is what you use when you want to ensure that only one instance of an object is ever created. In classical object-oriented programming languages, the concepts behind creating a singleton was a bit tricky to wrap your mind around because it involved a class that has both static and non-static properties and methods. I’m talking about JavaScript here though, so with JavaScript being a dynamic language without true classes, the JavaScript version of a singleton is excessively simple.

Why do you need the singleton?

Before I get into implementation details, I should discuss why the singleton pattern is useful for your applications. The ability to ensure you have only one instance of an object can actually come in quite handy. In server-side languages, you might use a singleton for handling a connection to a database because it's just a waste of resources to create more than one database connection for each request. Similarly, in front-end JavaScript, you might want to have an object that handles all AJAX requests be a singleton. A simple rule could be: if it has the exact same functionality every time you create a new instance, then make it a singleton.

This isn't the only reason to make a singleton, though. At least in JavaScript, the singleton allows you to namespace objects and functions to keep them organized and keep them from cluttering the global namespace, which as you probably know is a horrible idea, especially if you use third party code. Using the singleton for name-spacing is also referred to as the module design pattern.

Show me the singleton

To create a singleton, all you really need to do is create an object literal.


var Singleton = {
prop: 1,
another_prop: 'value',
method: function() {…},
another_method: function() {…}
};


You can also create singletons that have private properties and methods, but it's a little bit trickier as it involves using a closure and a self-invoking anonymous function. Inside a function, some local functions and/or variables are declared. You then create and return an object literal, which has some methods that refererence the variables and functions that you declared within the larger function's scope. That outer function is immediatly executed by placing () immediately after the function declaration and the resulting object literal is assigned to a variable. If this is confusing, then take a look over the following code and then I'll explain it some more afterward.




var Singleton = (function() {
var private_property = 0,
private_method = function () {
console.log('This is private');
}

return {
prop: 1,
another_prop: 'value',
method: function() {
private_method();
return private_property;
},
another_method: function() {…}
}
}());


The key is that when a variable is declared with var in front of it inside a function, that variable is only accessible inside the function and by functions that were declared within that function (the functions in the object literal for example). The return statement gives us back the object literal, which gets assigned to Singleton after the outer function executes itself.



Namespacing with the singleton


In JavaScript, namespacing is done by adding objects as properties of another object, so that it is one or more layers deep. This is useful for organizing code into logical sections. While the YUI JavaScript library does this to a degree that I feel is nearly excessive with numerous levels of namespacing, in general it is considered best practice to limit nesting namespaces to only a few lavels or less. The code below is an example of namespacing.



var Namespace = {
Util: {
util_method1: function() {…},
util_method2: function() {…}
},
Ajax: {
ajax_method: function() {…}
},
some_method: function() {…}
};

// Here's what it looks like when it's used
Namespace.Util.util_method1();
Namespace.Ajax.ajax_method();
Namespace.some_method();

The use of namespacing, as I said earlier, keeps global variables to a minumum. Heck, you can even have entire applications attached to a single object namespace named app if that's your perogative.

Literals

Integers


Floating-point literals
Boolean literals
String literals

Integers can be expressed in decimal (base 10), hexadecimal (base 16), and octal (base 8). A decimal integer literal consists of a sequence of digits without a leading 0 (zero). A leading 0 (zero) on an integer literal indicates it is in octal; a leading 0x (or 0X) indicates hexadecimal. Hexadecimal integers can include digits (0-9) and the letters a-f and A-F. Octal integers can include only the digits 0-7. Some examples of integer literals are: 42, 0xFFF, and-345.

Floating-point literals

A floating-point literal can have the following parts: a decimal integer, a decimal point ("."), a fraction (another decimal number), an exponent, and a type suffix. The exponent part is an "e" or "E" followed by an integer, which can be signed (preceded by "+" or "-"). A floating-point literal must have at least one digit, plus either a decimal point or "e" (or "E"). Some examples of floating-point literals are 3.1415, -3.1E12, .1e12, and 2E-12

String literals

A string literal is zero or more characters enclosed in double (") or single (') quotation marks. A string must be delimited by quotation marks of the same type; that is, either both single quotation marks or double quotation marks.

The following are examples of string literals: "blah", 'blah', "1234", "one line \n another line".

In addition to ordinary characters, you can also include special characters in strings, as shown in the last element in the preceding list.

Special Characters

Character
Meaning

\b
backspace

\f
form feed

\n
new line

\r
carriage return

\t
tab

\\
backslash character

For characters not listed in the preceding table, a preceding backslash is ignored, with the exception of a quotation mark and the backslash character itself. You can insert quotation marks inside strings by preceding them with a backslash. This is known as escaping the quotation marks. For example,

var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service."
document.write(quote)

The result of this would be He read "The Cremation of Sam McGee" by R.W. Service. To include a literal backslash inside a string, you must escape the backslash character. For example, to assign the file path c:\temp to a string, use the following:

var home = "c:\\temp"