« Back to Index

A few (of the many) different ways to create a Singleton in JavaScript. Be warned some of these examples require a lot more code to make them true Singletons. As is the case with most problems: simplicity is the key.

View original Gist on GitHub

Singleton.js

function Universe() {
    // do we have an existing instance?
    if (typeof Universe.instance === "object") {
        return Universe.instance; 
    }
    
    // proceed as normal 
    this.start_time = 0; 
    this.bang = "Big";
    
    // public methods
    this.setTime = function(time){
        this.start_time = time;
    }
    
    // cache (warning this property is public and so can be modified!)
    Universe.instance = this;
}

// testing
var uni = new Universe(); 
var uni2 = new Universe(); 
console.log(uni === uni2); // true

// view each instance to see their value
console.log(uni.start_time);
console.log(uni2.start_time);

// update the value for the first instance
uni.setTime(123);

// see both instances have updated (which means although different instances were created, the object is still a Singleton
console.log(uni.start_time);
console.log(uni2.start_time);

Singleton_2.js

function Universe() {
    // the cached instance 
    var instance = this;
    
    // proceed as normal 
    this.start_time = 0; 
    this.bang = "Big";
    
    // public methods
    this.setTime = function(time){
        this.start_time = time;
    }
    
    // rewrite the constructor
    Universe = function () {
        return instance;
    };
}

// testing
var uni = new Universe(); 
var uni2 = new Universe(); 
console.log(uni === uni2); // true

// view each instance to see their value
console.log(uni.start_time);
console.log(uni2.start_time);

// update the value for the first instance
uni.setTime(123);

// see both instances have updated (which means although different instances were created, the object is still a Singleton
console.log(uni.start_time);
console.log(uni2.start_time);

Singleton_3.js

var Singleton = (function(){ // We use a 'immediately invoked function expression' to create a Closure.
    // Private attribute that holds the single instance
    var uniqueInstance;
    
    // Private method which holds all of the normal Singleton code
    function Constructor(){
		// Private members (can't be accessed directly)
		var privateAttribute1 = false;
		var privateAttribute2 = [1, 2, 3];
		
		// Private method (can't be accessed directly)
		function privateMethod(){
			return 'my private method';
		}
		
		return {
			publicAttribute1: true,
			publicAttribute2: 10,
			
            // This method can be referred to as a 'Privileged' method as it has access to Private areas
			publicMethod: function(){
    			console.log('privateMethod() = ' + privateMethod()); // privileged access
				console.log('privateAttribute1 = ' + privateAttribute1); // privileged access 
				console.log('privateAttribute2 = ' + privateAttribute2); // privileged access
				console.log('this.publicAttribute1 = ' + this.publicAttribute1);
				console.log('this.publicAttribute2 = ' + this.publicAttribute2);
			}
		}
	}
	
	return {
		getInstance: function(){
			// Instantiate only if the instance doesn't exist.
			if (!uniqueInstance) {
				uniqueInstance = Constructor();
			}
			
			return uniqueInstance;
		}
	}
})();
	
/**
 * Now this singleton uses 'lazy loading' we must make sure we use the correct function calls
 *
 * e.g. 
 * Singleton.getInstance().publicMethod1();
 *
 * Notice we can 'chain' the methods because 'getInstance' returns the function object itself rather than a value.
 */
 
Singleton.getInstance().publicMethod();