Search code examples
javascriptdesign-patternssingleton

Does javascript singleton require double parentheses?


  • I created a Singleton-like function for a Google Sheet of mine;
  • Priv and Pub is my way of simulating Private and Public;
  • When I assign its instance to a variable, I need to type ()() so it works the way I want it to. I want to be able to type Priv.whateverProp
  • I've tried double parentheses in other places inside the Singleton function, but when I accomplish getting to use only one (), then the completions display apply, bind, call etc.
  • Then I have to getInstance()().completions** again to access the instance properties, but when I run the program, it says SingletonFinder().getInstance() is not a function
  • So I have to leave getInstance() with its single parentheses and type Priv().whaterverProp instead of Priv.whateverProp for the rest of the code, which I don't want.
  • Why do I have to type it this way let Priv = SingletonFinder().getInstance()() ?
function GetFinder(){
    let Pub = {}
    let Priv = SingletonFinder().getInstance()()
    // the rest of the code...
}

function SingletonFinder() {
    let Priv = {}
    let Pub = {}

    /** @type {Class_Finder} */
    Priv.instance = null;
    Priv.createInstance = function () {
        return Class_Finder
    }
    Pub.getInstance = function () {
        if(!Priv.instance) {
            Priv.instance = Priv.createInstance()
        }
        return Priv.instance
    };
    return Pub
}

function Class_Finder() {
    // properties
}

Solution

  • Years later, after reviewing this project, I can conclude that:

    • It is smarter to make use of Javascript's closure to manage access to values and functions; the logic behind this piece of code causes it to be lengthy, when it doesn't need to;
    • As pointed, I failed to reproduce the correct structure of the Singleton pattern in the example given, because it cannot assure there'll be a single instance of a Class available to the global scope;
    • As pointed, the need for an additional parentheses in SingletonFinder().getInstance()() is due to 2 factors: a) you can access the returning value's properties and methods, if they exist, immediatly after calling a function; b) getInstance's returning value is the Class_Finder function, so in order to access the returning value of Class_Finder, one more pair of parenthesis can be written right after the first one;

    The following code exemplifies why ()() is necessary to output 'true':

    const obj = {};
    const fn = ()=>{return true}
    obj.method = ()=>{return fn}
    
    console.log(obj.method) //output: function
    console.log(obj.method()) //output: function
    console.log(obj.method()()) //output: true
    

    Finally, it was all for fun! I've never been a pro coder and was just being a total beginner. Patterns fascinated me at the time as much as experimenting with coding and browsing the communities online.