Simplest/cleanest way to implement a singleton in JavaScript
Asked Answered
B

46

470

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

Bunkmate answered 25/9, 2009 at 20:5 Comment(2)
Downvote for the accepted answer not being a singleton at all. It's just a global variable.Kone
This is a ton of information, but really lays out the differences amongst the different JS design patterns. It helped me a lot: addyosmani.com/resources/essentialjsdesignpatterns/bookTekla
L
399

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 accessible here
    },
    publicMethod2: function () {
    }
  };
})();

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

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.

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'
// ...
Linda answered 25/9, 2009 at 20:10 Comment(19)
+1 Isn't it a bit strange to look for a "Singleton pattern" in a language with global variables???Klenk
Using the module pattern, how would a public member access another public member? I.e., how would publicMethod1 call publicMethod2?Arapaho
I think the pattern is like to have only one instance of the object in the whole code, disregarding how much times you initialize the object. Such as I commented (not my code) at #1636300Engler
@Tom, yeah, the pattern was born on class-based OOP languages -I remember a lot of implementations that involved a static getInstance method, and a private constructor-, but IMO, this is the most "simple" way to build a singleton object in Javascript, and at the end it meets the same purpose -a single object, that you can't initialize again (there's no constructor, it's just an object)-. About the code you linked, it has some problems, swap the a and b variable declarations and test a === window. Cheers.Beauchamp
@Arapaho - you have to access them by their public name. In this case publicMethod1 could have the line "myInstance.publicMethod2()". Private vars/methods can be used directly (ie. "privateMethod()").Pidgin
@Klenk – This is not strange to look for a "singleton pattern" in such language. many Object-oriented languages utilize global variables and still singletons are in use. Singleton is not only guarantee that there will be only one object of given class. Singleton has few more features: 1) it should be initialized at first use (which not only means delayed initialization, but also guarantee that object is really ready to be used) 2) it should be thread-safe. Module pattern can be replacement for singleton pattern but only in browser (and not always).Fite
@Fite Thanks for your comment. Still, I feel there is too much cargo cult behaviour around patterns, and too little thinking about what you really need and what tools you already have.Klenk
@CMS - Odd that the two options vary so much in 1. Complexity and 2. Resource Allocation ( Module takes up a bit more memory ). How do you choose...Privacy is good practice, but efficiency is good too :/ What about an in-between which uses a function object w/ a static member to keep only a single instance stored... similar to compiled languages...is this possible?Clarinda
Why isn't @sebarmelli's answer the most voted solution? https://mcmap.net/q/80046/-simplest-cleanest-way-to-implement-a-singleton-in-javascriptJudaica
@b.long 1. probably because it was posted 5 days after... 2. most people read the Accepted solution, upvote it and go back to work...Sullins
This should not be the accepted answer. This is not a singleton at all! This is just a global variable. There is a world of difference between the two.Kone
@RoyiNamir, thanks for the upvote. About the parens, I know, but I think they add clarity to the code, give a look to this article on the subject: michaux.ca/articles/an-important-pair-of-parensBeauchamp
@CMS addyosmani.com/resources/essentialjsdesignpatterns/book/… I think it's quite important to have always the same instance. Otherwise you're breaking the Singleton meaning for simplicity's sake.Engler
@Kone a singleton is a design pattern to make the same instance available across multiple classes by using the fact Java namespaces are global - it's a global variable nontheless - misko.hevery.com/2008/08/17/singletons-are-pathological-liarsWellgrounded
@BenjaminGruenbaum No. It's not. A global variable is a global variable. We already had a word for that. If Java doesn't have global variables I can see the attraction to using Singleton to get them, but Singleton as a pattern arose before the Java language. The Singleton pattern is not just about global availability of an instance, but about restricting the number of instances of a given class. Therefore, this answer is even less correct now that JavaScript has the class keyword than it was back in 2013 when I took issue with it.Kone
I can easily create a new object from the above code, I also tried to compare the same object on the console it says false. if it is a singleton, i would say it should not allow users to create a new object.Thumbscrew
Doesn't the ESM approach cause side effects on import? Which will, in turn, disable the use of tree shaking, for example.Lanthorn
"Singleton - Ensure that only one instance of a class is created and Provide a global access point to the object" How does this solution makes sure that only one instance of a class is created ? And can we call it a class anyways? My guess is using ES classes is a cleaner solution. And how would you make sure that imported module is accessible globally? Import myInstance and then window.myInstance = myInstance ? Or are there other ways to make it globally accessible ?Ruffianism
From a coding style perspective, the only feedback I would offer is that it has become a common practice to notate private functions by prepending a _ before it. Since the js module pattern doesn't actually offer private declarations as we would expect in a true class, function _myPrivateMethod() is a helpful visual cue when reviewing code to easily notate our public from private functions/methods. Inarguably this is not a 'standard' and certainly more preference, but it has become increasingly common, and I think it's helpful. shrugConcentrated
P
219

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();
Pastis answered 30/1, 2011 at 12:50 Comment(7)
Remark: The original constructor can be read again using delete instance.constructor: x = SingletonClass.getInstance();delete x.constructor;new x.constructor;Nauplius
var test = SingletonClass.getInstance() - does not look very clean or JS like. Other soultions that end up with a = new Foo(); b = new Foo(); a === b //trueCalabresi
Smells more like factory to me with the whole "getInstance" part.Dissymmetry
This is not a singleton because you can create multiple instances of it with Object.create.Neisse
Fiddle is brokenExert
That's the cleanest approach I've ever found on JS land yet as you nulled constructor before making one & only one instance of SingletonClass() . Clever ♥ . 10 years since anwered seem still legit other legacy @Pastis hahaTautog
This is still an anonymous class, no? Thoughts on this? I'm also not sure I like the this.name = ... "hack".Markettamarkey
H
131

In ES6 the right way to do this is:

class MyClass {
  constructor() {
    if (MyClass._instance) {
      throw new Error("Singleton classes can't be instantiated more than once.")
    }
    MyClass._instance = this;

    // ... Your rest of the constructor code goes after this
  }
}

var instanceOne = new MyClass() // Executes succesfully
var instanceTwo = new MyClass() // Throws error

Or, if you don't want an error to be thrown on the second instance creation, you can just return the last instance, like so:

class MyClass {
  constructor() {
    if (MyClass._instance) {
      return MyClass._instance
    }
    MyClass._instance = this;

    // ... Your rest of the constructor code goes after this
  }
}

var instanceOne = new MyClass()
var instanceTwo = new MyClass()

console.log(instanceOne === instanceTwo) // Logs "true"
Hoelscher answered 8/1, 2020 at 12:51 Comment(8)
Hi can you help me to know the difference between _instance and instance as I was using instance and code was not workingEvalyn
There's no technical difference in instance and _instance. It's just a naming convention in programming languages that we name private variables prepended with an underscore. I suspect the reason for your code to not work is that you are using this.instance instead of MyClass.instanceHoelscher
This can be improved with the use of a static private variable that will hold the instance, e.g. static #instance = null;. Otherwise, one can just modify the _instance property (set it to null) to create a second instance.Ecumenicism
@Ecumenicism I understand private class fields aren't implemented yet. This solution is specific to ES6. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Lyonnais
Are you missing the static getInstance() method? Or how do you use this implementation?Hungry
Regarding private class features static #instance = null; it appears that was only recently added - in ES2022.Dentoid
Singleton.instance = null; and then new MyClass() will create new instance.Agnesse
@Hoelscher Why would you even consider throwing an error?? Returning the last instance should be the default behaviour.Level
X
125

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
Xanthe answered 12/4, 2012 at 17:8 Comment(17)
@Esailija, I never said that singletons were a good idea. The question was about how to create a singleton in JavaScript, and this is the pattern you'd use to enforce that the constructor couldn't be executed multiple times. var singleton = {} is just an object instance, and is not a singleton. Certainly you could dynamically add properties to make the object suitably unique, but that doesn't make it a singleton, because the instance is of the Object "class", and you'd be able to create more than one.Xanthe
I never said anything about singletons being a bad or good idea. I said that your implementation of singleton is far more complicated than it needs to be because you confuse Java's limitations with the pattern as if you didn't understand it at all. It's like implementing strategy pattern by making constructor functions and methods when you can simply use anonymous functions for that in Javascript.Monopteros
@Esailija, it sounds to me like you don't understand the singleton pattern. The singleton pattern is a design pattern that restricts the Instantiation of a class to one object. var singleton = {} does not fit that definition.Xanthe
That only applies to languages like Java because of their limitations. var singleton = {} is how you implement singleton in Javascript.Monopteros
@Esailija, "In a prototype-based programming language, where objects but not classes are used..." JavaScript has the concept of classes, so that does not apply.Xanthe
By the way. Singleton is an anti pattern and should never be used in a managed sandboxed environment like JavaScript anyway. misko.hevery.com/2008/08/17/singletons-are-pathological-liars - youtube.com/watch?v=G32acYVd9LY blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx - jalf.dk/blog/2010/03/… - kore-nordmann.de/blog/0103_static_considered_harmful.html - phparch.com/2010/03/static-methods-vs-singletons-choose-neitherWellgrounded
@FlorianMargaine, JS has the concept of classes through instantiation via constructor functions. It's not that they are exactly classes in the way that strongly typed OOP languages such as Java or C# use.Xanthe
@FlorianMargaine I think he meant like #17008586Wellgrounded
To be fair, regardless what you think of Java or even about the pattern itself, this is the closest proper implementation of it you can find, IMO.Saphead
From my point of view may be usage of the singleton pattern legitimate (e.g. event handling). The global object is the simplest solution, but in a code when I create objects over constructor functions it looks inappropriate. I do not care, the Dispatcher is singleton (e.g. because I hate singleton or whatever). I want to use consistent approach and the singleton pattern gives me this option. It's all about personal preferences, but code should be consistent (because of readability).Keown
@FlorianMargaine, seeing your comment now that classes have been standardized as syntactic sugar for the prototype features that I've been using for years makes me feel well ahead of the curve. For that I should thank you.Xanthe
@BenjaminGruenbaum Well, I looked through one or two articles you linked and they all tried to explain via examples and focus on DI etc. which is good for testing I understand. I am genuinely seeking the answer to one question and which has been asked in comments in those articles too. How do you import logger in your modules without singleton or module pattern or some global accessor. With dependecy it gets messy as all classes have to hold logger either for them or for the classes they import.Sandon
"Additionally, the module pattern can be used to initialize a constructor, which could then be instantiated multiple times." In this case the constructor is that single object not the object that that constructor will return. ExplanationSandon
@user1533609 it's a tradeoff, you can inject the logger (like Angular) does or you an use a global. Note that since the logger is effectless (or at least should be) it doesn't suffer from many of the problems the articles I linked to raise. You can always override the global logger - the question is: do you need different parts of the app to do logging differently? If the answer is yes then you should probably inject the logger - otherwise it's fine that it's a global.Wellgrounded
@BenjaminGruenbaum logger was just a thing, others are socketIO instance as multiple instance create separate connections, DB( not sure though). But if you say they are effectless then it is ok. BTW, any way to override or mock the socketIO for testing etc. or are we out of luck?Sandon
Great article & google talk by Mishko Hevery on global state & singletons misko.hevery.com/2008/08/17/singletons-are-pathological-liars youtu.be/-FRm3VPhseI?si=8-hKBRlRnBF6UXKj&t=544Serra
best answer amongst all.Dashpot
N
39

In ECMAScript 2015 (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
Nissen answered 12/9, 2017 at 19:53 Comment(2)
Freezing would make sense if Singleton would be a wrapper around some other class and only have the instance field. As it is currently (instance set to this) this class might have other fields as well and freezing doesn't make sense imo.Lanthorn
Singleton.instance is open to be set to null by anybody using itAgnesse
T
31

If you're using node.JS then you can take advantage of node.JS caching mechanism and your Singleton will be as simple as:

class Singleton {
    constructor() {
        this.message = 'I am an instance';
    }
}
module.exports = new Singleton();

Please note that we export not the class Singleton but instance Singleton().

Node.JS will cache and reuse the same object each time it’s required.

For more details please check: Node.JS and Singleton Pattern

Timaru answered 22/9, 2021 at 6:57 Comment(4)
I don't see anything in OP regarding node.jsMarienbad
I don’t see anything explicitly about node.js too nor that it must be vanilla JS. Thus, I clearly added that this is for JS and node. You can’t really make it simpler and cleaner IF you use Node.JS! Moreover, looking at the upvotes, more people found this helpful than not.Timaru
@Timaru Thank you. This is the best way so far for my use case. Much appreciated.Rasure
This works in any js bundling context, whether node.js or browser bundled js afaik. Since in a bundle modules are iife, therefore creating a closure around the instantiated singleton, so every time you access the module value it is giving the object you originally instantiated.Bootlick
T
19

The following works in Node.js version 6:

class Foo {
  constructor(msg) {

    if (Foo.singleton) {
      return Foo.singleton;
    }

    this.msg = msg;
    Foo.singleton = this;
    return Foo.singleton;
  }
}

We test:

const f = new Foo('blah');
const d = new Foo('nope');
console.log(f); // => Foo { msg: 'blah' }
console.log(d); // => Foo { msg: 'blah' }
Torgerson answered 26/12, 2017 at 8:53 Comment(1)
Foo.singleton = null. This cause it to create new instance on next new Foo()Agnesse
A
13

The simplest/cleanest for me means also simply to understand and no bells & whistles as are much discussed in the Java version of the discussion:

What is an efficient way to implement a singleton pattern in Java?

The answer that would fit simplest/cleanest best there from my point of view is:

Jonathan's answer to What is an efficient way to implement a singleton pattern in Java?

And it can only partly be translated to JavaScript. Some of the difference in JavaScript are:

  • constructors can't be private
  • Classes can't have declared fields

But given the latest ECMA syntax, it is possible to get close with:

Singleton pattern as a JavaScript class example

 class Singleton {

  constructor(field1,field2) {
    this.field1=field1;
    this.field2=field2;
    Singleton.instance=this;
  }

  static getInstance() {
    if (!Singleton.instance) {
      Singleton.instance=new Singleton('DefaultField1','DefaultField2');
    }
    return Singleton.instance;
  }
}

Example Usage

console.log(Singleton.getInstance().field1);
console.log(Singleton.getInstance().field2);

Example Result

DefaultField1
DefaultField2
Apologist answered 12/8, 2019 at 4:8 Comment(6)
I reviewed well-received answers, but I think this one is under-attended. +1 btwHoneysuckle
I'm new to JavaScript coming from java and must ask, how does this stopping from doing new Singleton() and by so the Singleton pattern is brokenMaidy
@Maidy - it doesn't it's just by convention that you call getInstanceApologist
this is the best answer. Singleton has to make use of static.Gage
is the above constructor is private?Penelopa
@Penelopa if there is such a thing as private constructors in the meantime in javascript yet - what's the standard saying these days?Apologist
C
12

If you want to use classes:

class Singleton {
  constructor(name, age) {
    this.name = name;
    this.age = age;
    if(this.constructor.instance)
      return this.constructor.instance;
    this.constructor.instance = this;
  }
}
let x = new Singleton('s', 1);
let y = new Singleton('k', 2);

Output for the above will be:

console.log(x.name, x.age, y.name, y.age) // s 1 s 1

Another way of writing Singleton using function

function AnotherSingleton (name,age) {
  this.name = name;
  this.age = age;
  if(this.constructor.instance)
    return this.constructor.instance;
  this.constructor.instance = this;
}

let a = new AnotherSingleton('s', 1);
let b = new AnotherSingleton('k', 2);

Output for the above will be:

console.log(a.name, a.age, b.name, b.age) // s 1 s 1
Clements answered 16/4, 2020 at 14:18 Comment(1)
It doesn't make sense for the constructor of a singleton to have arguments.Level
T
8

I got this example from the *JavaScript Patterns Build Better Applications with Coding and Design Patterns book (by Stoyan Stefanov). In case you need some simple implementation class like a singleton object, you can use an immediate function as in the following:

var ClassName;

(function() {
    var instance;
    ClassName = function ClassName() {
        // If the private instance variable is already initialized, return a reference
        if(instance) {
            return instance;
        }
        // If the instance is not created, save a pointer of the original reference
        // to the private instance variable.
        instance = this;

        // All constructor initialization will be here
        // i.e.:
        this.someProperty = 0;
        this.someMethod = function() {
            // Some action here
        };
    };
}());

And you can check this example by following test case:

// Extending defined class like singleton object using the new prototype property
ClassName.prototype.nothing = true;
var obj_1 = new ClassName();

// Extending the defined class like a singleton object using the new prototype property
ClassName.prototype.everything = true;
var obj_2 = new ClassName();

// Testing makes these two objects point to the same instance
console.log(obj_1 === obj_2); // Result is true, and it points to the same instance object

// All prototype properties work
// no matter when they were defined
console.log(obj_1.nothing && obj_1.everything
            && obj_2.nothing && obj_2.everything); // Result true

// Values of properties which are defined inside of the constructor
console.log(obj_1.someProperty); // Outputs 0
console.log(obj_2.someProperty); // Outputs 0

// Changing property value
obj_1.someProperty = 1;

console.log(obj_1.someProperty); // Output 1
console.log(obj_2.someProperty); // Output 1

console.log(obj_1.constructor === ClassName); // Output true

This approach passes all test cases while a private static implementation will fail when a prototype extension is used (it can be fixed, but it will not be simple) and a public static implementation less advisable due to an instance is exposed to the public.

jsFiddly demo.

Treasury answered 21/1, 2014 at 6:44 Comment(0)
P
8

Using ES6 classes and private static fields. Invoking new instances of the Singleton class will return the same instance. The instance variable is also private and can't be accessed outside the class.

class Singleton {
  // # is a new Javascript feature that denotes private
  static #instance;

  constructor() {
    if (!Singleton.#instance) {
      Singleton.#instance = this
    } 
    return Singleton.#instance
  }

  get() {
    return Singleton.#instance;
  }
}

const a = new Singleton();
const b = new Singleton();
console.log(a.get() === b.get()) // true
console.log(Singleton.instance === undefined) // true
Premillennialism answered 21/8, 2022 at 9:14 Comment(0)
H
7

There is more than one way to skin a cat :) Depending on your taste or specific need you can apply any of the proposed solutions. I personally go for Christian C. Salvadó's 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 variables, so it's pretty much the same as:

var SingletonClass = {
    myFunction: function () {
        // Do stuff
    },
    instance: 1
}
Haft answered 28/6, 2011 at 1:4 Comment(1)
Code snippet 2 contains a syntax error. You can't write this.f(){}Hessney
F
7

I deprecate my answer, see my other one.

Usually the module pattern (see Christian C. Salvadó's answer) which is not the singleton pattern is good enough. However, one of the features of the singleton is that its initialization is delayed till the object is needed. The 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
Fite answered 2/11, 2011 at 22:45 Comment(1)
Why would you load the module if it's not needed? And when you need to load the module, then you load the module, and it initializes.Monopteros
F
6

Short answer:

Because of the non-blocking nature of JavaScript, singletons in JavaScript are really ugly in use. Global variables will give you one instance through the whole application too without all these callbacks, and module pattern gently hides internals behind the interface. See Christian C. Salvadó's answer.

But, since you wanted a singleton…

var singleton = function(initializer) {

  var state = 'initial';
  var instance;
  var queue = [];

  var instanceReady = function(createdInstance) {
    state = 'ready';
    instance = createdInstance;
    while (callback = queue.shift()) {
      callback(instance);
    }
  };

  return function(callback) {
    if (state === 'initial') {
      state = 'waiting';
      queue.push(callback);
      initializer(instanceReady);
    } else if (state === 'waiting') {
      queue.push(callback);
    } else {
      callback(instance);
    }
  };

};

Usage:

var singletonInitializer = function(instanceReady) {
  var preparedObject = {property: 'value'};
  // Calling instanceReady notifies the singleton that the instance is ready to use
  instanceReady(preparedObject);
}
var s = singleton(singletonInitializer);

// Get the instance and use it
s(function(instance) {
  instance.doSomething();
});

Explanation:

Singletons give you more than just one instance through the whole application: their initialization is delayed till the first use. This is really a big thing when you deal with objects whose initialization is expensive. Expensive usually means I/O and in JavaScript I/O always mean callbacks.

Don't trust answers which give you interface like instance = singleton.getInstance(), they all miss the point.

If they don't take a callback to be run when an instance is ready, then they won't work when the initializer does I/O.

Yeah, callbacks always look uglier than a function call which immediately returns an object instance. But again: when you do I/O, callbacks are obligatory. If you don't want to do any I/O, then instantiation is cheap enough to do it at program start.

Example 1, cheap initializer:

var simpleInitializer = function(instanceReady) {
  console.log("Initializer started");
  instanceReady({property: "initial value"});
}

var simple = singleton(simpleInitializer);

console.log("Tests started. Singleton instance should not be initalized yet.");

simple(function(inst) {
  console.log("Access 1");
  console.log("Current property value: " + inst.property);
  console.log("Let's reassign this property");
  inst.property = "new value";
});
simple(function(inst) {
  console.log("Access 2");
  console.log("Current property value: " + inst.property);
});

Example 2, initialization with I/O:

In this example, setTimeout fakes some expensive I/O operation. This illustrates why singletons in JavaScript really need callbacks.

var heavyInitializer = function(instanceReady) {
  console.log("Initializer started");
  var onTimeout = function() {
    console.log("Initializer did his heavy work");
    instanceReady({property: "initial value"});
  };
  setTimeout(onTimeout, 500);
};

var heavy = singleton(heavyInitializer);

console.log("In this example we will be trying");
console.log("to access singleton twice before it finishes initialization.");

heavy(function(inst) {
  console.log("Access 1");
  console.log("Current property value: " + inst.property);
  console.log("Let's reassign this property");
  inst.property = "new value";
});

heavy(function(inst) {
  console.log("Access 2. You can see callbacks order is preserved.");
  console.log("Current property value: " + inst.property);
});

console.log("We made it to the end of the file. Instance is not ready yet.");
Fite answered 18/10, 2013 at 20:36 Comment(4)
Through trials and tribulations with other singleton answers that didn't cut it, I landed on resulting code remarkably similar to this.Turbit
For one reason or another, this is the only answer that makes sense to me. The other answers all remind me of the goon show episode where three men try to climb a wall four people high, by climbing on each others shoulders recursively.Gratuity
The calback stacking is the thing I really needed! Thanks!!Gratuity
This approach never actually gives you a singleton as: singleton(singletonInitializer) !== singleton(singletonInitializer) they are two different instances. The resulting function you returned can be used to attach more callbacks to the instance, but doesn't strictly specify that only one instance of this type can be created. Which is the whole point of a singleton.Mandeville
A
6

I think I have found the cleanest way to program in JavaScript, but you'll need some imagination. I got this idea from a working technique in the book JavaScript: The Good Parts.

Instead of using the new keyword, you could create a class like this:

function Class()
{
    var obj = {}; // Could also be used for inheritance if you don't start with an empty object.

    var privateVar;
    obj.publicVar;

    obj.publicMethod = publicMethod;
    function publicMethod(){}

    function privateMethod(){}

    return obj;
}

You can instantiate the above object by saying:

var objInst = Class(); // !!! NO NEW KEYWORD

Now with this work method in mind, you could create a singleton like this:

ClassSingleton = function()
{
    var instance = null;

    function Class() // This is the class like the above one
    {
        var obj = {};
        return obj;
    }

    function getInstance()
    {
        if( !instance )
            instance = Class(); // Again no 'new' keyword;

        return instance;
    }

    return { getInstance : getInstance };
}();

Now you can get your instance by calling

var obj = ClassSingleton.getInstance();

I think this is the neatest way as the complete "Class" is not even accessible.

Anserine answered 2/9, 2014 at 12:13 Comment(3)
But with this technique you could have more than one instance. That is not right.Linhliniment
I wouldn't think so, you can't even access the class without going through getInstance. Could you elaborate?Anserine
David Maes Sorry but I did not notice the validation in the second example. I apologize.Linhliniment
H
5

Christian C. Salvadó's and zzzzBov's answer have both given wonderful answers, but just to add my own interpretation based on my having moved into heavy Node.js development from PHP/Zend Framework where singleton patterns were common.

The following, comment-documented code is based on the following requirements:

  • one and only one instance of the function object may be instantiated
  • the instance is not publicly available and may only be accessed through a public method
  • the constructor is not publicly available and may only be instantiated if there is not already an instance available
  • the declaration of the constructor must allow its prototype chain to be modified. This will allow the constructor to inherit from other prototypes, and offer "public" methods for the instance

My code is very similar to zzzzBov's answer except I've added a prototype chain to the constructor and more comments that should help those coming from PHP or a similar language translate traditional OOP to JavaScript's prototypical nature. It may not be the "simplest" but I believe it is the most proper.

// Declare 'Singleton' as the returned value of a self-executing anonymous function
var Singleton = (function () {
    "use strict";
    // 'instance' and 'constructor' should not be available in a "public" scope
    // here they are "private", thus available only within
    // the scope of the self-executing anonymous function
    var _instance=null;
    var _constructor = function (name) {
        this.name = name || 'default';
    }

    // Prototypes will be "public" methods available from the instance
    _constructor.prototype.getName = function () {
        return this.name;
    }

    // Using the module pattern, return a static object
    // which essentially is a list of "public static" methods
    return {
        // Because getInstance is defined within the same scope
        // it can access the "private" 'instance' and 'constructor' vars
        getInstance:function (name) {
            if (!_instance) {
                console.log('creating'); // This should only happen once
                _instance = new _constructor(name);
            }
            console.log('returning');
            return _instance;
        }
    }

})(); // Self execute

// Ensure 'instance' and 'constructor' are unavailable
// outside the scope in which they were defined
// thus making them "private" and not "public"
console.log(typeof _instance); // undefined
console.log(typeof _constructor); // undefined

// Assign instance to two different variables
var a = Singleton.getInstance('first');
var b = Singleton.getInstance('second'); // passing a name here does nothing because the single instance was already instantiated

// Ensure 'a' and 'b' are truly equal
console.log(a === b); // true

console.log(a.getName()); // "first"
console.log(b.getName()); // Also returns "first" because it's the same instance as 'a'

Note that technically, the self-executing anonymous function is itself a singleton as demonstrated nicely in the code provided by Christian C. Salvadó. The only catch here is that it is not possible to modify the prototype chain of the constructor when the constructor itself is anonymous.

Keep in mind that to JavaScript, the concepts of “public” and “private” do not apply as they do in PHP or Java. But we have achieved the same effect by leveraging JavaScript’s rules of functional scope availability.

Hammerless answered 16/9, 2012 at 21:38 Comment(2)
Multiple instances can be created from your code: var a = Singleton.getInstance('foo'); var b = new a.constructor('bar');Xanthe
@zzzzBov: I'm just getting errors trying that in my Fiddle: jsfiddle.net/rxMu8Barthold
P
5

You could just do:

var singleton = new (function() {
  var bar = 123

  this.foo = function() {
    // Whatever
  }
})()
Ploch answered 22/7, 2013 at 3:15 Comment(1)
This seems to be a neat way to skip the getInstance method and get a more simple solution. But keep in mind that the singleton will execute as soon as the file is parsed, meaning that DOM listeners must be wrapped in a $(document).ready functionExert
S
5

The clearest answer should be this one from the book Learning JavaScript Design Patterns by Addy Osmani.

var mySingleton = (function () {

  // Instance stores a reference to the singleton
  var instance;

  function init() {

    // Singleton

    // Private methods and variables
    function privateMethod(){
        console.log( "I am private" );
    }

    var privateVariable = "I'm also private";

    var privateRandomNumber = Math.random();

    return {

      // Public methods and variables
      publicMethod: function () {
        console.log( "The public can see me!" );
      },

      publicProperty: "I am also public",

      getRandomNumber: function() {
        return privateRandomNumber;
      }

    };

  };

  return {

    // Get the singleton instance if one exists
    // or create one if it doesn't
    getInstance: function () {

      if ( !instance ) {
        instance = init();
      }

      return instance;
    }

  };

})();
Stockman answered 10/10, 2017 at 7:28 Comment(0)
F
5

This is how I implement singleton pattern using ES6 features. Yes, I know this does not look like an Object-oriented approach, but I find this method is easy to implement and a clean way to implement.

const Singleton = (() => {
  var _instance = !_instance && new Object('Object created....');
  return () => _instance;
})();

//************************************************************************

var instance1 = Singleton();
var instance2 = Singleton();
console.log(instance1 === instance2); // true
Frambesia answered 15/11, 2022 at 3:54 Comment(0)
H
4

For me the cleanest way to do so is:

const singleton = new class {
    name = "foo"
    constructor() {
        console.log(`Singleton ${this.name} constructed`)
    }
}

With this syntax you are certain your singleton is and will remain unique. You can also enjoy the sugarness of class syntax and use this as expected.

(Note that class fields require node v12+ or a modern browser.)

Hedgehop answered 1/12, 2019 at 0:19 Comment(0)
W
3

This should work:

function Klass() {
   var instance = this;
   Klass = function () { return instance; }
}
Wampumpeag answered 4/7, 2012 at 2:40 Comment(4)
Test = Klass; t1 = new Test(); t2 = new Test(); - no opportunity to rename the class or pick a different namespace.Xanthe
@Xanthe I didn't quite understand what you are trying to say. Are you saying it should not allow other functions to reference the "Singleton" function? What is wrong with this solution?Toga
@SudhansuChoudhary, frankly, I can't speak accurately as to what I happened to be thinking when I wrote this eight years ago. If I had to guess, it was probably a complaint about the fragility of the solution when used in the global namespace, as was common in 2012. With modern scripting practices, the complaint no longer seems relevant, however I will add that it's not a good idea to use singleton's in JS in 2020 (it wasn't a good idea in 2012 either).Xanthe
@Xanthe I'm not a Singleton fan either, now I understand where you were coming from when you made that comment, fragility of the solution in global namespace should have been a huge concern. Thanks for the clarification.Toga
S
3

I believe this is the simplest/cleanest and most intuitive way though it requires ECMAScript 2016 (ES7):

export default class Singleton {

  static instance;

  constructor(){
    if(instance){
      return instance;
    }

    this.state = "duke";
    this.instance = this;
  }

}

The source code is from: adam-bien.com

Straight answered 25/8, 2017 at 3:50 Comment(1)
This is completely wrong and would throw error on calling new Singleton()Hoelscher
A
3

I've found the following to be the easiest singleton pattern, because using the new operator makes this immediately available within the function, eliminating the need to return an object literal:

var singleton = new (function () {

  var private = "A private value";

  this.printSomething = function() {
      console.log(private);
  }
})();

singleton.printSomething();
Accompanist answered 16/2, 2018 at 5:40 Comment(0)
T
2

Following is the snippet from my walkthrough to implement a singleton pattern. This occurred to me during an interview process and I felt that I should capture this somewhere.

/*************************************************
 *     SINGLETON PATTERN IMPLEMENTATION          *
 *************************************************/

// Since there aren't any classes in JavaScript, every object
// is technically a singleton if you don't inherit from it
// or copy from it.
var single = {};


// Singleton Implementations
//
// Declaring as a global object...you are being judged!

var Logger = function() {
  // global_log is/will be defined in the GLOBAL scope here
  if(typeof global_log === 'undefined'){
    global_log = this;
  }
  return global_log;
};


// The below 'fix' solves the GLOABL variable problem, but
// the log_instance is publicly available and thus can be
// tampered with.
function Logger() {
  if(typeof Logger.log_instance === 'undefined') {
    Logger.log_instance = this;
  }

  return Logger.log_instance;
};


// The correct way to do it to give it a closure!

function logFactory() {
  var log_instance; // Private instance
  var _initLog = function() { // Private init method
    log_instance = 'initialized';
    console.log("logger initialized!")
  }
  return {
    getLog : function(){ // The 'privileged' method
      if(typeof log_instance === 'undefined') {
        _initLog();
      }
      return log_instance;
    }
  };
}


/***** TEST CODE ************************************************

// Using the Logger singleton
var logger = logFactory(); // Did I just give LogFactory a closure?

// Create an instance of the logger
var a = logger.getLog();

// Do some work
// Get another instance of the logger
var b = logger.getLog();

// Check if the two logger instances are same
console.log(a === b); // true
*******************************************************************/

The same can be found on my gist page.

Tollgate answered 23/8, 2013 at 17:27 Comment(0)
L
2

My two cents: I have a constructor function (CF), for example,

var A = function(arg1){
  this.arg1 = arg1
};

I need just every object created by this CF to be the same.

var X = function(){
  var instance = {};
  return function(){ return instance; }
}();

Test

var x1 = new X();
var x2 = new X();
console.log(x1 === x2)
Lydie answered 3/12, 2015 at 7:25 Comment(0)
V
2

Singleton:

Ensure a class has only one instance and provides a global point of access to it.

The singleton pattern limits the number of instances of a particular object to just one. This single instance is called the singleton.

  • defines getInstance() which returns the unique instance.
  • responsible for creating and managing the instance object.

The singleton object is implemented as an immediate anonymous function. The function executes immediately by wrapping it in brackets followed by two additional brackets. It is called anonymous because it doesn't have a name.

Sample Program

var Singleton = (function () {
    var instance;

    function createInstance() {
        var object = new Object("I am the instance");
        return object;
    }

    return {
        getInstance: function () {
            if (!instance) {
                instance = createInstance();
            }
            return instance;
        }
    };
})();

function run() {

    var instance1 = Singleton.getInstance();
    var instance2 = Singleton.getInstance();

    alert("Same instance? " + (instance1 === instance2));
}

run()
Vereen answered 18/7, 2017 at 7:35 Comment(0)
M
2

Here is a simple example to explain the singleton pattern in JavaScript.

var Singleton = (function() {
    var instance;
    var init = function() {
        return {
            display:function() {
                alert("This is a singleton pattern demo");
            }
        };
    };
    return {
        getInstance:function(){
            if(!instance){
                alert("Singleton check");
                instance = init();
            }
            return instance;
        }
    };
})();

// In this call first display alert("Singleton check")
// and then alert("This is a singleton pattern demo");
// It means one object is created

var inst = Singleton.getInstance();
inst.display();

// In this call only display alert("This is a singleton pattern demo")
// it means second time new object is not created,
// it uses the already created object

var inst1 = Singleton.getInstance();
inst1.display();
Marketing answered 24/9, 2017 at 17:20 Comment(1)
This is good. It creates a global context and Singleton is not a function anymore and declaring any variable inside gets a global context.Sanskritic
G
2
function Once() {
    return this.constructor.instance || (this.constructor.instance = this);
}

function Application(name) {
    let app = Once.call(this);

    app.name = name;

    return app;
}

If you are into classes:

class Once {
    constructor() {
        return this.constructor.instance || (this.constructor.instance = this);
    }
}

class Application extends Once {
    constructor(name) {
        super();

        this.name = name;
    }
}

Test:

console.log(new Once() === new Once());

let app1 = new Application('Foobar');
let app2 = new Application('Barfoo');

console.log(app1 === app2);
console.log(app1.name); // Barfoo
Greensboro answered 22/8, 2019 at 22:47 Comment(0)
S
2
let MySingleton = (function () {
  var _instance
  function init() {
    if(!_instance) {
      _instance = { $knew: 1 }
    }
    return _instance
  }
  let publicAPIs = {
    getInstance: function() {
      return init()
    }
  }
  // this prevents customize the MySingleton, like MySingleton.x = 1
  Object.freeze(publicAPIs) 
  // this prevents customize the MySingleton.getInstance(), like MySingleton.getInstance().x = 1
  Object.freeze(publicAPIs.getInstance())
  return publicAPIs
})();
Sideways answered 23/6, 2021 at 3:44 Comment(0)
A
2
class Singelton {
    static #instance;

    #testValue;

    constructor() {
        if (Singelton.#instance instanceof Singelton) {
            return Singelton.#instance;
        }

        Singelton.#instance = this;
        return Singelton.#instance;
    }

    get testValue() {
        return this.#testValue;
    }

    set testValue(value) {
        this.#testValue = value;
    }
}

test:

let x = new Singelton();
x.testValue = 123;

let y = new Singelton();

console.log({isSingelton: x === y, testValueFromY: y.testValue});
Ara answered 5/7, 2022 at 0:19 Comment(0)
C
2

This knowledge is base from I am learning Java, though Java and Javascript is different, the concept of Singleton and how Java do it is just the same. In my opinion, The class style from JS is clean by itself rather than var initialization.

class Singleton {
    // use hashtag which entails that the variable can only be accessed from self scope
    static #instance = null;
    static getInstance() {
        if (this.#instance === null) this.#instance = new Singleton();
        return this.#instance;
    }

    // some class property
    hello = 'world';

    // or initialize the variable in the constructor, depend on your preference
    constructor() {
        // this.hello = 'world';
    }

    /* you can also add parameters on the constructor & getInstance
     * e.g. 
     * static getInstance(param1, param2) {...new Singleton(param1, param2)}
     * constructor(param1, param2) {...}
     */

}




// this is the same code for java and normal way for singleton for class
// just use static so you can get instance


// testing the singleton
var s1,s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();

// you cannot access the property, immediately
if (Singleton.hello === undefined) console.log('getInstance so you can access this');

console.log(s1.hello);
// result: "world"

console.log(s2.hello);
// result: "world"


// set the value of Singleton object
s2.hello = "hi";
    console.log(s1.hello);
    // result: "hi"

    console.log(s2.hello);
    // result: "hi"
// this is just an evidence which means that they are the same even in property level

if (s1 === s2) console.log("S1 & S2 is the same object");
// result: "S1 & S2 is the same object"

// don't use something like `var s1 = new Singleton();`
// this will defeat your purpose of just (1 object), one instance of class
Canticle answered 5/10, 2022 at 22:15 Comment(2)
Singleton Design Pattern LinkCanticle
This is not a Singleton pattern. Nothing stops the consumer to just use new Singleton() instead of Singleton.getInstance() and it will create a new instance of the classQuinidine
T
1
function Unicode()
{
  var i = 0, unicode = {}, zero_padding = "0000", max = 9999;

  // Loop through code points
  while (i < max) {
    // Convert decimal to hex value, find the character,
    // and then pad zeroes to the code point
    unicode[String.fromCharCode(parseInt(i, 16))] = ("u" + zero_padding + i).substr(-4);
    i = i + 1;
  }

  // Replace this function with the resulting lookup table
  Unicode = unicode;
}

// Usage
Unicode();

// Lookup
Unicode["%"]; // Returns 0025
Ti answered 25/9, 2009 at 20:6 Comment(0)
S
1

I needed several singletons with:

  • lazy initialisation
  • initial parameters

And so this was what I came up with:

createSingleton ('a', 'add', [1, 2]);
console.log(a);

function createSingleton (name, construct, args) {
    window[name] = {};
    window[construct].apply(window[name], args);
    window[construct] = null;
}

function add (a, b) {
    this.a = a;
    this.b = b;
    this.sum = a + b;
}
  • args must be Array for this to work, so if you have empty variables, just pass in []

  • I used the window object in the function, but I could have passed in a parameter to create my own scope

  • name and construct parameters are only String in order for window[] to work, but with some simple typechecking, window.name and window.construct are also possible.

Sumptuary answered 29/5, 2012 at 8:30 Comment(0)
F
1

Module pattern: in "more readable style". You can see easily which methods are public and which ones are private

var module = (function(_name){
   /* Local Methods & Values */
   var _local = {
      name : _name,
      flags : {
        init : false
      }
   }

   function init(){
     _local.flags.init = true;
   }

   function imaprivatemethod(){
     alert("Hi, I'm a private method");
   }

   /* Public Methods & variables */

   var $r = {}; // This object will hold all public methods.

   $r.methdo1 = function(){
       console.log("method1 calls it");
   }

   $r.method2 = function(){
      imaprivatemethod(); // Calling private method
   }

   $r.init = function(){
      inti(); // Making 'init' public in case you want to init manually and not automatically
   }

   init(); // Automatically calling the init method

   return $r; // Returning all public methods

})("module");

Now you can use public methods like

module.method2(); // -> I'm calling a private method over a public method alert("Hi, I'm a private method")

http://jsfiddle.net/ncubica/xMwS9/

Faefaeces answered 9/7, 2013 at 15:34 Comment(0)
C
1

Another way - just insure the class can not new again.

By this, you can use the instanceof op. Also, you can use the prototype chain to inherit the class. It's a regular class, but you can not new it. If you want to get the instance, just use getInstance:

function CA()
{
    if(CA.instance)
    {
        throw new Error('can not new this class');
    }
    else
    {
        CA.instance = this;
    }
}


/**
 * @protected
 * @static
 * @type {CA}
 */
CA.instance = null;

/* @static */
CA.getInstance = function()
{
    return CA.instance;
}


CA.prototype =
/** @lends CA# */
{
    func: function(){console.log('the func');}
}

// Initialise the instance
new CA();

// Test here
var c = CA.getInstance()
c.func();
console.assert(c instanceof CA)

// This will fail
var b = new CA();

If you don't want to expose the instance member, just put it into a closure.

Cynarra answered 29/7, 2013 at 12:1 Comment(0)
S
1

This is also a singleton:

function Singleton() {
    var i = 0;
    var self = this;

    this.doStuff = function () {
        i = i + 1;
        console.log('do stuff', i);
    };

    Singleton = function () { return self };
    return this;
}

s = Singleton();
s.doStuff();
Semipro answered 24/5, 2015 at 13:29 Comment(0)
P
1

You can do it with decorators like in this example below for TypeScript:

class YourClass {

    @Singleton static singleton() {}

}

function Singleton(target, name, descriptor) {
    var instance;
    descriptor.value = () => {
        if(!instance) instance = new target;
        return instance;
    };
}

Then you use your singleton like this:

var myInstance = YourClass.singleton();

As of this writing, decorators are not readily available in JavaScript engines. You would need to make sure your JavaScript runtime has decorators actually enabled or use compilers like Babel and TypeScript.

Also note that the singleton instance is created "lazy", i.e., it is created only when you use it for the first time.

Pullover answered 26/9, 2016 at 11:22 Comment(1)
TypeScript is not a compiler. It is a programming language. Can you clarify (by editing your answer)?Palp
M
1

Simple Example

class Settings {

  constructor() {
    if (Settings.instance instanceof Settings) {
      return Settings.instance;
    }
    this.settings = {
      id: Math.floor(Math.random() * 4000),
      name: "background",
    };
    Object.freeze(this.settings);
    Object.freeze(this);
    Settings.instance = this;
  }

}

var o1 = new Settings();
var o2 = new Settings();

console.dir(o1);
console.dir(o2);

if (o1 === o2) {
  console.log("Matched");
}
Minster answered 27/7, 2020 at 15:21 Comment(0)
Y
0

I like to use a combination of the singleton pattern with the module pattern, and init-time branching with a Global NS check, wrapped within a closure.

In a case where the environment isn't going to change after the initialization of the singleton, the use of an immediately invoked object-literal to return a module full of utilities that will persist for some duration should be fine.

I'm not passing any dependencies, just invoking the singletons within their own little world - the only goal being to: create a utilities module for event binding / unbinding (device orientation / orientation changes could also work in this case).

window.onload = ( function( _w ) {
    console.log.apply( console, ['it', 'is', 'on'] );
    ( {
        globalNS : function() {
            var nameSpaces = ["utils", "eventUtils"],
                nsLength = nameSpaces.length,
                possibleNS = null;

            outerLoop:
            for ( var i = 0; i < nsLength; i++ ) {
                if ( !window[nameSpaces[i]] ) {
                    window[nameSpaces[i]] = this.utils;
                    break outerLoop;
                };
            };
        },
        utils : {
            addListener : null,
            removeListener : null
        },
        listenerTypes : {
            addEvent : function( el, type, fn ) {
                el.addEventListener( type, fn, false );
            },
            removeEvent : function( el, type, fn ) {
                el.removeEventListener( type, fn, false );
            },
            attachEvent : function( el, type, fn ) {
                el.attachEvent( 'on'+type, fn );
            },
            detatchEvent : function( el, type, fn ) {
                el.detachEvent( 'on'+type, fn );
            }
        },
        buildUtils : function() {
            if ( typeof window.addEventListener === 'function' ) {
                this.utils.addListener = this.listenerTypes.addEvent;
                this.utils.removeListener = this.listenerTypes.removeEvent;
            } else {
                this.utils.attachEvent = this.listenerTypes.attachEvent;
                this.utils.removeListener = this.listenerTypes.detatchEvent;
            };
            this.globalNS();
        },
        init : function() {
            this.buildUtils();
        }
    } ).init();
} ( window ) );
Ynes answered 23/12, 2013 at 18:57 Comment(0)
E
0

You did not say "in the browser". Otherwise, you can use Node.js modules. These are the same for each require call. Basic example:

The contents of foo.js:

const circle = require('./circle.js');
console.log(`The area of a circle of radius 4 is ${circle.area(4)}`);

The contents of circle.js:

const PI = Math.PI;

exports.area = (r) => PI * r * r;

exports.circumference = (r) => 2 * PI * r;

Note that you cannot access circle.PI, as it is not exported.

While this does not work in the browser, it is simple and clean.

Ewen answered 22/6, 2016 at 21:9 Comment(0)
W
0

The main key is to understand the closure's importance behind this. So a property even inside the inner function will be private with the help of the closure.

var Singleton = function () {
    var instance;

    function init() {

       function privateMethod() {
           console.log("private via closure");
       }

       var privateVariable = "Private Property";

       var privateRandomNumber = Math.random(); // This is also private

       return {
           getRandomNumber: function () {  // Access via getter in init call
               return privateRandomNumber;
           }
       };
    };

    return {
        getInstance: function () {

            if (!instance) {
                instance = init();
            }
            return instance;
        }
    };
};
Winkle answered 6/4, 2017 at 19:14 Comment(0)
T
0

You can return the same instance in every new execution -

function Singleton() {
    // lazy 
    if (Singleton.prototype.myInstance == undefined) {
        Singleton.prototype.myInstance = { description: "I am the instance"};
    }
    return Singleton.prototype.myInstance;
}

a = new Singleton();
b = new Singleton();
console.log(a); // { description: "I am the instance"};
console.log(b); // { description: "I am the instance"};
console.log(a==b); // true
Toothsome answered 17/10, 2018 at 7:57 Comment(0)
A
0

Simply use a class expression:

const singleton = new (class {
    hello() { return 'world'; }
})();

console.log(singleton.hello()); //=> world
Afterwards answered 2/11, 2022 at 17:46 Comment(0)
D
-1

A singleton in JavaScript is achieved using the module pattern and closures.

Below is the code which is pretty much self-explanatory -

// Singleton example.
var singleton = (function() {
  var instance;

  function init() {
    var privateVar1 = "this is a private variable";
    var privateVar2 = "another var";

    function pubMethod() {
      // Accessing private variables from inside.
      console.log(this.privateVar1);
      console.log(this.privateVar2);
      console.log("inside of a public method");
    };
  }

  function getInstance() {
    if (!instance) {
      instance = init();
    }
    return instance;
  };

  return {
    getInstance: getInstance
  }
})();

var obj1 = singleton.getInstance();
var obj2 = singleton.getInstance();

console.log(obj1 === obj2); // Check for type and value.
Dixil answered 23/4, 2017 at 13:11 Comment(0)
G
-1

So to be fair the simplest answer is usually the best. An object literal is always a single instance. Not much reason for anything more complex other than, perhaps allocation of memory on demand.

That being said, here is a classical implementation of a singleton using ES6.

  • The instance "field" is "private". This really means we hide the instance as a property of the constructor. Somewhere not Constructor.prototype, which will be available to the instance through prototipical inheritance.
  • The constructor is "private". We really are just throwing an error when the caller is not the static getInstance method.

Also of note. It’s important to understand what the keyword this means in different contexts.

In the constructor, this points to the instance created.

In the static getInstance method, this points to the left of the dot, Universe constructor function which, is an object like most things in JS and can hold properties.

class Universe {
    constructor() {
       if (!((new Error).stack.indexOf("getInstance") > -1)) {
           throw new Error("Constructor is private. Use static method getInstance.");  
       } 
       this.constructor.instance = this;
       this.size = 1;
    }
    static getInstance() {
        if (this.instance) {
            return this.instance;
        }
        return new this;
    }
    expand() {
        this.size *= 2;
        return this.size;
    }
}


console.log(Universe.getInstance())
console.log(Universe.getInstance().expand())
console.log(Universe.getInstance())
console.log(new Universe())
Gilleod answered 29/7, 2022 at 5:31 Comment(3)
Universe.instance is not exactly private, everybody can access and even overwrite it. It also is inherited by subclasses (although subclassing singletons is a bad idea anyway).Machzor
right, hence the use of the quotations "private". This is a hacky imitation. It works if you don't go looking into [[prototype]] to find the reference to use. Best use case is an object literal IMO.Gilleod
It's just confusing given there are actual private fields now, as shown in numerous of the other answersMachzor
M
-3
var singleton = (function () {

    var singleton = function(){
        // Do stuff
    }
    var instance = new singleton();
    return function(){
        return instance;
    }
})();

A solution without the getInstance method.

Matisse answered 30/9, 2020 at 15:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.