Question

I have some reading about the two ways of creating a singleton in javascript - simple object literal way and another with closure technique if we want to use private variables.

I am looking to create a utility function, for example

Singleton(classname);

Whatever class - "constructor function" i pass in here as argument the Singleton method converts this class into a Singleton object, PLUS after calling the new Classname() if somebody again fires new classname() he/she gets some new Error ( "Already instantiated once, this is Singleton" );

Use case is as below -

function Circle() {this.name = "Circle";}
SingleTon(Circle);
var circle1 = new Circle(); // returns the circle instance
var circle2 = new Circle(); // throws Error "Already instantiated once, this is Singleton"

I am just trying to define the "Singleton" method here.

I have seen similar example where a getInstance method is used to get the instance like - Singleton.getInstance(Circle) etc. but I am looking for the particular question above where another programmer habitual to creating an instance in the "new" way tries to fire new Circle(); second time somewhere in his code and receives an error.

Creating a singleton this way is one problem but main problem is throwing the "Error" for which to my understanding the Circle constructor needs to be modified somewhere in the Singleton function, not sure how to accomplish this.

Is there any solution ?

Thanks in advance !!

Was it helpful?

Solution

function Singleton(param){
    var count = 0, old = window[param];
    window[param] = function(){
         if(++count <= 1) return old;
         else alert('NO WAY!'); 
    }
}

You would call it as:

Singleton('Circle');

Demo: http://jsfiddle.net/maniator/7ZFmE/

Remember this only works if Circle or any other function class is in the global window namespace. Anything in any other namespace would need some more manipulation to make it work fully.

OTHER TIPS

Try this:

Circle = function () {
  if (!(this instanceof Circle)) {
    // called as function
    return Circle.singleton || (Circle.singleton = new Circle());
  }
  // called as constructor

  this.name = "the circle";
};

Now, without new operator, you get the singleton or a new one using

var mycircle = Circle();

Beware I'm using a global name for the example, you may also do

var Circle = window.Circle = function () { //...

You could of course also create a single instance Object with the possibility of using closures with something like:

var singlecircle = (new function(name) {
         this.name = name || "Default circle";}('squared')
    );
singlecircle.name; //=> 'squared'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top