4

I use the following Singleton pattern in JavaScript:

  var exampleClass =(function(){ 
                        //private
                        var a ="test"; 
                        function PrivateMethod()
                        {
                            return a;
                        }
                        //public
                        return{  
                            Test: function() { 
                                   alert(PrivateMethod()); 
                                  } 
                        }
                      })(); 

As I read through StackOverflow I see a lot of other implementations of Singleton and I start to doubt if I couldn't make mine better. I hope someone can tell me what's right or wrong about doing it this way.

Ruben-J
  • 2,663
  • 15
  • 33
  • What is the actual use this Pattern in Javascript? – madhairsilence Nov 07 '12 at 08:51
  • Mostly for separating all functions and variables from other functions, but I also have for instance a popuphelper which uses its private variables to keep the last state. I want all developers to use that class and not instantiate a new class. So only one "instance" may exist in the application. To keep some, for example ,coordinates of the popup as global variables doesn't feel right. I think it's much better to use Popup.Open() and handle all the logic and variables inside that class. – Ruben-J Nov 07 '12 at 09:00
  • Some good examples:: http://stackoverflow.com/questions/1479319/simplest-cleanest-way-to-implement-singleton-in-javascript – Sudhir Bastakoti Nov 07 '12 at 09:04
  • I know the examples, but i know a lot of people use my implementation and i just want to know why and if i should switch to another pattern. – Ruben-J Nov 07 '12 at 09:12

5 Answers5

3

It depends what you want to achieve as the different implementations will have different benefits and limitations.

The simplest implementation is just an object literal:

var singleton = {
    property: "foo",
    method: function() {
        alert('bar');
    }
}

The implementation you mention in the question allows public and private methods by encapsulating the methods in a closure and returning what should be exposed.

Here is an alternative which similarly would allow public and private methods and is more extensible:

function MySingletonClass() {

  if ( arguments.callee._singletonInstance )
    return arguments.callee._singletonInstance;
  arguments.callee._singletonInstance = this;

  this.Foo = function() {
    // ...
  }
}

var a = new MySingletonClass()
var b = MySingletonClass()
Print( a === b ); // prints: true
DanS
  • 17,550
  • 9
  • 53
  • 47
1

This is mine.

Differences are:

  • all functions declared at top
  • all functions are private by default
  • all functions have access to other functions
  • public functions are mapped at bottom

Improvements are:

  • if you want to move a function from private to public or viceversa, you don't have to move code, only change mapping at bottom of code
  • all functions have access to both private and public functions (because all functions are private by default)

    var exampleClass =(function(){ 
    
                    //private
                    var a ="test"; 
    
                    //declare here all functions 
                    //(both for pass jslint validation and is good to have a list
                    //of all available functions, in case of classes with a lot of code
    
                    var PrivateMethod,
                    Test1,
                    Test2;
    
                    PrivateMethod = function()
                    {
                        return a;
                    };
    
                    Test1 = function()
                    {
                        return PrivateMethod();
                    };
    
                    Test2 = function()
                    {
                        return Test1();
                    };
    
    
                    //public
                    //Expose function you want to have pubblic
                    return{  
                        Test1: Test1,
                        Test2: Test2 
                    }
                  })(); 
    
Draykos
  • 773
  • 7
  • 16
0

I'm using this pattern:

var SingletonConstructor;
(function() {
    var instance;
    SingletonConstructor = function() {

        if (typeof instance !== 'undefined')
           return instance;

        var a = "a";

        function PrivateMethod() {
            return a;
        }

        return instance = this;
    };
})();
Damask
  • 1,754
  • 1
  • 13
  • 24
0

This is how Google Closure do it:

http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js#427

Tim Green
  • 3,571
  • 2
  • 23
  • 23
0

I love the following pattern:

function MyClass(){
    if(MyClass.instance){
        return MyClass.instance;
    }
    MyClass.instance = this;

    //constructor code goes here
}

var a = new MyClass();
var b = new MyClass();

console.log(a == b); //true
Van Coding
  • 24,244
  • 24
  • 88
  • 132