2

So I've got a Singleton "class" that works pretty well:

function Base_Singleton () {
    if ( Base_Singleton.prototype._singletonInstance )
        return Base_Singleton.prototype._singletonInstance;
    else
        return Base_Singleton.prototype._singletonInstance = this;
}

This works great. You make multiple instances if you want, and they all reflect the changes of each other:

var sing1 = new Base_Singleton();
var sing2 = new Base_Singleton();
sing1.foo = "bar";
sing2.foo === "bar"; // true

So what I want now is to be able to create multiple Singleton interfaces, with their own info. I'm open to any way of accomplishing this. The two methods that came to mind were either extending or making a factory.

When I try extending, the new object just gets the prototype of the Base_Singleton, so it's not extending anything it's just creating another instance.

I figure the best way is via a Factory that can create a new object each time:

var Singleton_Factory = new function () {
    // Let's just assume this is in a web environment
    var global = global || window; 

    /**
     * Build a new object with Singleton functionality.
     * Singleton functionality based from https://goo.gl/YfmiTH
     *
     * The idea is that there is an instance of the object shared through the 
     * singleton's prototype. You can create as many 'new' Singletons as you
     * desire, but they all will mirror the same prototypical object.
     * 
     * @param  {string} singletonName The name of the new Singleton, and its 
     *                                prototype
     * @param  {object} namespace     The namespace to add the new object to
     * 
     * @return {object}               The newly created Singleton
     */
    this.make = function ( singletonName, namespace ) {
        // Default to global object as defined earlier
        namespace = namespace || global;
        // If there is a shared _singletonInstance, return that
        if ( namespace[singletonName].prototype._singletonInstance )
            return namespace[singletonName].prototype._singletonInstance;
        //  If there isn't one, create and return 'this'
        else
            return namespace[singletonName].prototype._singletonInstance = this;
    }
}

Problem here is that I'm trying to use prototype on undefined.

How can I create a factory that can create a new prototype with the functionality of Base_Singleton?

xyhhx
  • 6,384
  • 6
  • 41
  • 64
  • 8
    [Singleton is an anti-pattern](//misko.hevery.com/2008/08/17/singletons-are-pathological-liars/), moreover singletons aren't needed in JavaScript (just make an object literal). They are nothing but sugar for global mutable shared state in Java to make up for the language's lack of global scope. In JavaScript if you need a global variable (what a singleton essentially is) just put a variable on the outermost scope. Basically, because singletons are an anti-pattern, and because they don't make up for a language's lack in JS - they are much more rarely used in code. – Benjamin Gruenbaum Jun 18 '15 at 21:30
  • 1
    Modules are a good JavaScript pattern to accomplish what you're proposing with "singletons". – ericbn Jun 18 '15 at 21:43
  • @BenjaminGruenbaum just wanted to point out your link is not working (for me) is that right? – AGE Jun 18 '15 at 21:46
  • "*You make multiple instances*" - of a singleton? That contradicts its definition. Btw, there's no reason to use prototypes for single objects - nothing is shared. – Bergi Jun 18 '15 at 21:48
  • 1
    What exactly are you trying to create? A factory that `make`s singleton constructors? Or actually one that does create instances? – Bergi Jun 18 '15 at 21:50
  • Btw, [`new function(){…}` is an antipattern](http://stackoverflow.com/q/10406552/1048572) – Bergi Jun 18 '15 at 21:52
  • @BenjaminGruenbaum A global object literal is not the same as what I want. This could be for a codebase that others will work on, and will likely try to create new instances of the object. – xyhhx Jun 19 '15 at 13:31
  • @Bergi I'm kinda open to either giving me a `new`ly created object or it could return the constructor – xyhhx Jun 19 '15 at 13:32
  • 1
    I think it would be wise to define `why` a singleton isn't very useful in JavaScript instead of simply defining yet another cliche `this is an anti-pattern` excuse... > JavaScript isn't `as` useful in JavaScript because JavaScript is single-threaded... etc... – Edward J Beckett Nov 09 '15 at 00:39
  • 1
    Kind of sad slew of replies I got here. Nobody has tried to help me, instead to show me that they disagree with what I'm doing in the first place. I didn't ask if it was okay or not to do this, I am asking HOW to do this. – xyhhx Nov 09 '15 at 19:41

0 Answers0