0

I was just looking into ways of defining singletons in JavaScript, and after looking into a few samples I thought about the following way which I haven't found anywhere:

function MyClass() {
   if (MyClass._sharedInstance === undefined) {
      // actual constructor code

      MyClass._sharedInstance = this;
   }
   return MyClass._sharedInstance;
}

MyClass._sharedInstance = undefined;

Seems to work fine... but the fact that I couldn't find this anywhere makes me suspicious. Is there any reason not to do a singleton that way, especially considering the many little pitfalls of JavaScript. I know that by simply doing a var MyClass = { /* MyClass Stuff */ } I can achieve a singleton with less code, but for the sake of consistency I would like to define all my classes using prototypes.

5
  • What advantage does this have over the "module" pattern? Commented Jun 11, 2014 at 23:23
  • 3
    What I don't understand is what problem this solves. How will it be used? Commented Jun 11, 2014 at 23:23
  • 1
    "for the sake of consistency I would like to define all my classes using prototypes" - but for a singleton object you don't need a class, and no prototype to share anything! Commented Jun 11, 2014 at 23:28
  • As I said, the only reason I'd do this is for consistency. @Bergi you are probably right, I am fairly new to OOP in JavaScript so a lot of my thinking is likely to still be influenced by "real" OOP languages. In my head, a singleton is just a special kind of class, so it makes sense to define it as such. Seems to be different in JS, though... Commented Jun 12, 2014 at 8:22
  • I'd say that you are too much influenced by "class-only" languages, and you should start with some real OOP languages :-) Commented Jun 12, 2014 at 12:22

1 Answer 1

1

The proposed solution does not seem to "solve" anything1; as such, I recommend a standard variation of a "simple module pattern" using an idiomatic IIFE:

MySingleton = (function () {
    // This function is only executed once
    // and whatever is returned is the singleton.
    return {
       // Expose members here
    };
})();

Depending on specific need a new'ed object could also be returned, making this pattern flexible without the need to introduce a separate "singleton" field and guard, e.g.

MySingleton = (function () {
    // Contrived, but valid - any object returned
    // functions as the singleton.
    function MyClass {}
    return new MyClass();
})();

1If anything, it may lead to some "WTF?" moments when new MyClass() returns a shared/singleton object which is not "normal" behavior.

Sign up to request clarification or add additional context in comments.

2 Comments

You are right that it does not solve anything besides allowing for a consistent way to define "classes" in JavaScript using prototyping. You are also probably right about the WTF-moment, but the same thing could be said about singletons in Java/C#/..., couldn't it? Anyway, I will go with the standard behaviour as you suggested and not use the prototyping solution.
@user2864740: Notice that your second example (with the local MyClass, returning an instance from the IEFE) is equivalent to the new (function MyClass(){…}) approach and has the same issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.