Javascript: best Singleton pattern

JavascriptSingletonDesign Patterns

Javascript Problem Overview


> Possible Duplicate:
> Simplest/Cleanest way to implement singleton in JavaScript?

I'm using this pattern for singletons, in the example the singleton is PlanetEarth:

var NAMESPACE = function () {
	
	var privateFunction1 = function () {
		privateFunction2();
	};
	
	var privateFunction2 = function () {
		alert('I\'m private!');
	};
	
	var Constructors = {};
	
	Constructors.PlanetEarth = function () {
		privateFunction1();
		privateFunction2();
	};
	
	Constructors.PlanetEarth.prototype = {
		someMethod: function () {
			if (console && console.log) {
				console.log('some method');				
			}
		}
	};
	
	Constructors.Person = function (name, address) {
		this.name = name;
		this.address = address;
	};
	
	Constructors.Person.prototype = {
		walk: function () {
			alert('STOMP!');
		}
	};
	
	return {
		Person: Constructors.Person, // there can be many
		PlanetEarth: new Constructors.PlanetEarth() // there can only be one!
	};
	
}();

Since PlanetEarth's constructor remains private, there can only be one.

Now, something tells me that this self-cooked thing isn't the best one can do, mostly because I don't have an academic education and I tend to solve problems in stupid ways. What would you propose as a better alternative my method, where better is defined as stylistically better and/or more powerful?

Javascript Solutions


Solution 1 - Javascript

(1) UPDATE 2019: ES7 Version

class Singleton {
    static instance;

    constructor() {
        if (instance) {
            return instance;
        }

        this.instance = this;
    }

    foo() {
        // ...
    }
}

console.log(new Singleton() === new Singleton());

(2) ES6 Version

class Singleton {
    constructor() {
        const instance = this.constructor.instance;
        if (instance) {
            return instance;
        }

        this.constructor.instance = this;
    }

    foo() {
        // ...
    }
}

console.log(new Singleton() === new Singleton());

Best solution found: http://code.google.com/p/jslibs/wiki/JavascriptTips#Singleton_pattern

function MySingletonClass () {

  if (arguments.callee._singletonInstance) {
    return arguments.callee._singletonInstance;
  }

  arguments.callee._singletonInstance = this;

  this.Foo = function () {
    // ...
  };
}

var a = new MySingletonClass();
var b = MySingletonClass();
console.log( a === b ); // prints: true

For those who want the strict version:

(function (global) {
  "use strict";
  var MySingletonClass = function () {
   
    if (MySingletonClass.prototype._singletonInstance) {
      return MySingletonClass.prototype._singletonInstance;
    }

    MySingletonClass.prototype._singletonInstance = this;
  
    this.Foo = function() {
      // ...
    };
  };

var a = new MySingletonClass();
var b = MySingletonClass();
global.result = a === b;
  
} (window));

console.log(result);

Solution 2 - Javascript

Why use a constructor and prototyping for a single object?

The above is equivalent to:

var earth= {
    someMethod: function () {
        if (console && console.log)
            console.log('some method');                             
    }
};
privateFunction1();
privateFunction2();

return {
    Person: Constructors.Person,
    PlanetEarth: earth
};

Solution 3 - Javascript

Extending the above post by Tom, if you need a class type declaration and access the singleton instance using a variable, the code below might be of help. I like this notation as the code is little self guiding.

function SingletonClass(){
    if ( arguments.callee.instance )
	    return arguments.callee.instance;
    arguments.callee.instance = this;
}


SingletonClass.getInstance = function() {
    var singletonClass = new SingletonClass();
    return singletonClass;
};

To access the singleton, you would

var singleTon = SingletonClass.getInstance();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKaze no KoeView Question on Stackoverflow
Solution 1 - JavascriptTom RoggeroView Answer on Stackoverflow
Solution 2 - JavascriptbobinceView Answer on Stackoverflow
Solution 3 - JavascriptarunponView Answer on Stackoverflow