DEV Community

LG
LG

Posted on • Edited on

Static vs. Singleton in JavaScript

Keyword of static

Idea is simple : ask yourself how to prevent function (class) from being instantiated ? We cannot just remove keyword new from specification , neither ask user of JS politely not to use of keyword new , that probably would be silly to expect from JS hackers , right ? The reason I've started talking about keyword new because in works hand in hand with this. within function's constructor – in layman's terms – the keyword new works hand in hand with constructor itself . What we can do is to null the constructor whereas a constructor in ES5 standard is clearly a function itself –> if we nulled constructor , the constructor would resolve to null , instead of plain object literal , but a brilliant idea born recently for me – what if we swap constructor with object literal containing some logic within ? – as we will see the "constructorless" (as what I called it) function is nothing else than an object literal , such object literal has no constructor – in the result "no constructor , well then no instantiation could be made upon" – simple , right ? Let's see in action :

let funcObjectLiteral = (function () {
  /* blank */
}.prototype.constructor = {
  /* blank is overwritten by the following : */ 
_this: "local_scope",
  _getter: function () {
    return `Hello from STATIC ${this._this}`;
  }
});
new funcObjectLiteral() /* () */; // funcObjectLiteral is not a constructor # hereby parenthesis are optional as no (args) passed
/* although */ console.log(funcObjectLiteral); // Chrome output : {_this: 'local_scope', _getter: ƒ}
Enter fullscreen mode Exit fullscreen mode

Now interesting part , if singleton is one & the only one instance of single object (from class factory between the lines), then nulled function (as shown above) or a simple object literal technically should also be called as a singleton ? , well not exactly , let's prove it is not a singleton :

let a = {happy : "new_year"}
let b = {happy : "new_year"}
// common sense a === b won't be same :
a === b // false
Enter fullscreen mode Exit fullscreen mode

Singleton

A singleton should result to true between comparisons to show that is one & the same instance as referenced to . Let's see in action :

// Credits to Sebastiano Armeli a.k.a. sebarmeli
let SingletonFactory = (function () {
  function SingletonClass() {
    // single instance
  }
  let instance;
  return {
    getInstance: function () {
      if (instance === undefined) {
        instance = new SingletonClass();
        /* before nulling the constructor , make one & only one instance of SingletonClass() */
        instance.constructor = null; // Hide the constructor so the returned object cannot be instantiated
      }
      return instance;
    }
  };
})();

let a = SingletonFactory.getInstance();
// SingletonClass {constructor: null}
let b = SingletonFactory.getInstance();
// SingletonClass {constructor: null}
console.log(a === b); // true # as expected
Enter fullscreen mode Exit fullscreen mode

Why Singleton ? – Well Singleton is every there, even I myself am a Singleton who loves programming more than women (joking) , nevertheless the true reason to exploit Singleton , actually a few of them – see for About Singleton in Useful references below for a more comprehensive overview ! However , within the article about Singleton provided , it's recommended by the author to prevent the Singleton from further modification being applied upon with Object.freeze() which I think is a great idea , although be advised – it's one way operation (no way back, unless some strong refs emulations would be planned B upfront) !

EXTRA NOTE : In terms of the Singleton as immutable lazy-loading structure , this is somehow indicates idea on how Svelte store may work conceptually under the hood , what do you think – any ideas ? – please leave a comment in the comment section below , otherwise stay stunned for the next one , see ya !


Useful references

Top comments (0)