Simplest/Cleanest way to implement singleton in JavaScript?

Simplest/Cleanest way to implement singleton in JavaScript?

What is the simplest/cleanest way to implement singleton pattern in JavaScript?

Solutions/Answers:

Solution 1:

I think the easiest way is to declare a simple object literal:

var myInstance = {
  method1: function () {
    // ...
  },
  method2: function () {
    // ...
  }
};

If you want private members on your singleton instance, you can do something like this:

var myInstance = (function() {
  var privateVar = '';

  function privateMethod () {
    // ...
  }

  return { // public interface
    publicMethod1: function () {
      // all private members are accesible here
    },
    publicMethod2: function () {
    }
  };
})();

This has been called the module pattern, it basically allows you to encapsulate private members on an object, by taking advantage of the use of closures.

UPDATE: I would like to add that if you want to prevent the modification of the singleton object, you can freeze it, using the ES5 Object.freeze method.

That will make the object immutable, preventing any modification to the its structure and values.

Additionally I would like to mention that if you are using ES6, you can represent a singleton using ES Modules very easily, and you can even hold private state by declaring variables at the module scope:

// my-singleton.js
const somePrivateState = []

function privateFn () {
  // ...
}

export default {
  method1() {
    // ...
  },
  method2() {
    // ...
  }
}

Then you can simply import the singleton object to use it:

import myInstance from './my-singleton.js'
// ...

Solution 2:

I think the cleanest approach is something like:

var SingletonFactory = (function(){
    function SingletonClass() {
        //do stuff
    }
    var instance;
    return {
        getInstance: function(){
            if (instance == null) {
                instance = new SingletonClass();
                // Hide the constructor so the returned object can't be new'd...
                instance.constructor = null;
            }
            return instance;
        }
   };
})();

Afterwards, you can invoke the function as

var test = SingletonFactory.getInstance();

Solution 3:

I’m not sure I agree with the module pattern being used as a replacement for a singleton pattern. I’ve often seen singletons used and abused in places where they’re wholly unnecessary, and I’m sure the module pattern fills many gaps where programmers would otherwise use a singleton, however the module pattern is not a singleton.

module pattern:

var foo = (function () {
    "use strict";
    function aPrivateFunction() {}
    return { aPublicFunction: function () {...}, ... };
}());

Everything initialized in the module pattern happens when Foo is declared. Additionally, the module pattern can be used to initialize a constructor, which could then be instantiated multiple times. While the module pattern is the right tool for many jobs, it’s not equivalent to a singleton.

singleton pattern:

short form

var Foo = function () {
    "use strict";
    if (Foo._instance) {
        //this allows the constructor to be called multiple times
        //and refer to the same instance. Another option is to
        //throw an error.
        return Foo._instance;
    }
    Foo._instance = this;
    //Foo initialization code
};
Foo.getInstance = function () {
    "use strict";
    return Foo._instance || new Foo();
}

long form, using module pattern

var Foo = (function () {
    "use strict";
    var instance; //prevent modification of "instance" variable
    function Singleton() {
        if (instance) {
            return instance;
        }
        instance = this;
        //Singleton initialization code
    }
    //instance accessor
    Singleton.getInstance = function () {
        return instance || new Singleton();
    }
    return Singleton;
}());

In both versions of the Singleton pattern that I’ve provided, the constructor itself can be used as the accessor:

var a,
    b;
a = new Foo(); //constructor initialization happens here
b = new Foo();
console.log(a === b); //true

If you don’t feel comfortable using the constructor this way, you can throw an error in the if (instance) statement, and stick to using the long form:

var a,
    b;
a = Foo.getInstance(); //constructor initialization happens here
b = Foo.getInstance();
console.log(a === b); //true

I should also mention that the singleton pattern fits well with the implicit constructor function pattern:

function Foo() {
    if (Foo._instance) {
        return Foo._instance;
    }
    //if the function wasn't called as a constructor,
    //call it as a constructor and return the result
    if (!(this instanceof Foo)) {
        return new Foo();
    }
    Foo._instance = this;
}
var f = new Foo(); //calls Foo as a constructor
-or-
var f = Foo(); //also calls Foo as a constructor

Solution 4:

In es6:

class Singleton {
  constructor () {
    if (!Singleton.instance) {
      Singleton.instance = this
    }
    // Initialize object
    return Singleton.instance
  }
  // Properties & Methods
}

const instance = new Singleton()
Object.freeze(instance)

export default instance

Solution 5:

There is more than one ways to skin a cat 🙂 Depending on your taste or specific need you can apply any of the proposed solutions. I personally go for CMS’ first solution whenever possible (when you don’t need privacy). Since the question was about the simplest and cleanest, that’s the winner. Or even:

var myInstance = {}; // done!

This (quote from my blog) …

var SingletonClass = new function() { 
    this.myFunction() { 
        //do stuff 
    } 
    this.instance = 1; 
}

doesn’t make much sense (my blog example doesn’t either) because it doesn’t need any private vars, so it’s pretty much the same as:

var SingletonClass = { 
    myFunction: function () { 
        //do stuff 
    },
    instance: 1 
}

Solution 6:

I deprecate my answer, see my other one.

Usually module pattern (see CMS’ answer) which is NOT singleton pattern is good enough. However one of the features of singleton is that its initialization is delayed till object is needed. Module pattern lacks this feature.

My proposition (CoffeeScript):

window.singleton = (initializer) ->
  instance = undefined
  () ->
    return instance unless instance is undefined
    instance = initializer()

Which compiled to this in JavaScript:

window.singleton = function(initializer) {
    var instance;
    instance = void 0;
    return function() {
        if (instance !== void 0) {
            return instance;
        }
        return instance = initializer();
    };
};

Then I can do following:

window.iAmSingleton = singleton(function() {
    /* This function should create and initialize singleton. */
    alert("creating");
    return {property1: 'value1', property2: 'value2'};
});


alert(window.iAmSingleton().property2); // "creating" will pop up; then "value2" will pop up
alert(window.iAmSingleton().property2); // "value2" will pop up but "creating" will not
window.iAmSingleton().property2 = 'new value';
alert(window.iAmSingleton().property2); // "new value" will pop up