Skip to content

Instantly share code, notes, and snippets.

@you-think-you-are-special
Created February 18, 2015 10:52
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save you-think-you-are-special/e4a89de3ae347b1d4d76 to your computer and use it in GitHub Desktop.
Save you-think-you-are-special/e4a89de3ae347b1d4d76 to your computer and use it in GitHub Desktop.
ES6 Singleton example. Use: import Singleton from 'Singleton'; let instance = Singleton.instance;
'use strict';
/**
* Created by Alexander Litvinov
* Email: alexander@codeordie.ru
* May be freely distributed under the MIT license
*/
let singleton = Symbol();
let singletonEnforcer = Symbol();
class Singleton {
/**
* @param enforcer
*/
constructor(enforcer) {
if (enforcer !== singletonEnforcer) {
throw "Cannot construct singleton"
}
}
/**
* @returns Singleton
*/
static get instance() {
if (!this[singleton]) {
this[singleton] = new Singleton(singletonEnforcer);
}
return this[singleton];
}
}
export default Singleton;
@mrme44
Copy link

mrme44 commented May 18, 2015

Couldn't one get around this by calling new Singleton(singletonEnforcer). A function would, however, have to be injected into the Singleton class to gain access to singletonEnforcer. Chrome does not yet supported ES6 modules, so I can't actually test this out yet :(.

I have come up with the following function that I've been using to create singletons. There is a way around this method too. See if you can figure it out ;).

I use this function

function makeSingleton(instance){
  let className = instance.__proto__.constructor.name
  eval(className + "= function(){throw `${className} is a Singleton. Use ${className}.getInstance() instead`}")
  eval(className + ".getInstance = function(){return instance}")
}

Any class can then be made into a singleton by calling makeSingleton(this) in the constructor.

@mrme44
Copy link

mrme44 commented May 18, 2015

Also

//this function could be called outside of a class to make a class a singleton, however, the class's constructor cannot take in any arguments for this to work.
function makeSingleton2(theClass){
  const instance = new theClass();
  eval(theClass.name + "= () => instance") //Chrome doesn't support arrow function yet, but I believe I used it properly.
}

@schankam
Copy link

@mrme44 You should use babel man ! Work with ES6 now anywhere !

@mrme44
Copy link

mrme44 commented May 22, 2015

@schankam, I'll have to check Babel out. I tried using some other ES6 transpiler once; I don't remember what it was called, but it didn't work out so well.

@you-think-you-are-special
Copy link
Author

@schankam, @mrme44 thanks for yours comments! I used this with Babel. Works fine!

@StevenLangbroek
Copy link

If I understand CommonJS + the browser implementations correctly, the output of a module is cached, so export default new MyClass() will result in something that behaves as a singleton (only a single instance of this class will ever exist per process/client depending on env it's running in).

@milankarunarathne
Copy link

@StevenLangbroek export default new MyClass() pattern is using in ReactJS dispacher which is a single component for a ReactJS app. I think, you are correct about it.
Refer: https://gist.github.com/milankarunarathne/c565aa5970987aeca88b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment