-2

I come across singleton pattern, it's quite tricky to understand how to implement it, and I know some people would suggest to avoid it most of the time, so below is specific singleton variation that I find it easy to understand, but somehow I feel that this is not the best implementation of this pattern, can you guys suggest better form of this pattern.

var Foo = (function () {
   
    var instance;
    var _priVar = 2;
    var log = function() {
      console.log("Hello");
    };
  
    function Singleton(x, y) {
        if (instance) {
            return instance;
        }
        
        this.name = x;
        this.age = y + _priVar;
        this.log = log;
      
        instance = this;
    }
    Singleton.getInstance = function () {
        return instance || new Singleton();
    }
    return Singleton;
}());

and my goal is that when we do following

var a = new Foo("Bob", 24); var b = new Foo(); var c = Foo(); var d = Foo.getInstance();

we will still get

 a == b // true
 a == c // true
 a == d // true
 a.name // 'Bob'
 b.age // 26
 c.log // 'Hello'
 d.name // 'Bob'
Flimzy
  • 60,850
  • 13
  • 104
  • 147
xcode
  • 1,317
  • 3
  • 11
  • 20
  • What you want , you code works well. – passion Sep 23 '16 at 06:18
  • `we will still get` - you do get that - what's the problem? – Jaromanda X Sep 23 '16 at 06:20
  • Most of all, [there's something wrong with the singleton pattern itself](http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons), and your particular implementation just inherits these problems. – Bergi Sep 23 '16 at 06:50

1 Answers1

1

The simplest singleton, also known as module pattern, consists of an object literal:

var foo = (function () {
    var x = "Bob",
        y = 24,
        _priVar = 2;

    function log() {
        console.log("Hello");
    }

    return {
        name: x,
        age: y + _priVar,
        log: log
    };
}());

If you want to introduce lazy initialisation, you can use an extra getInstance function like in your implementation:

var getFoo = (function () {
    var instance = null;
    return function getFooInstance() {
        if (instance) return instance;

        var x = "Bob",
            y = 24,
            _priVar = 2;

        function log() {
            console.log("Hello");
        }

        return instance = {
            name: x,
            age: y + _priVar,
            log: log
        };
    };
}());

A singleton should never use a constructor like in your code, that's just unnecessary. If you feel a need to pass arguments for initialisation, don't make it a singleton.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
  • thanks for the advice on last line, can you explain why we should never use constructor in singleton? other than 'unnecessary', is there any other reason? – xcode Sep 23 '16 at 07:07
  • It creates an empty and useless prototype, it might inadvertedly be called without `new`, dunno. It's just overly complicated. Go for the simple factory function. – Bergi Sep 23 '16 at 07:11