Creating a Javascript Singleton

Synopsis

This article will demonstrate how to create a singleton for use in Javascript programs.

Singleton?

In object oriented programming, a singleton is a class that is instantiated only once. Most programmers find the idea of a singleton counter-intuitive when first introduced to them. Most of the time, we create classes so we can create many instances of them; after all, it doesn't make much sense to create a database application that can work with only a single employee at a time.

However, there are times when we want to create a system within a program; for example, let's pretend we're writing a game and want to create a sound system. In a procedural language like C, we'd create a series of functions all prefixed with the same value.

  /* This is a comment, i.e. ignored by the computer */
  /* Procedural sound system example */
  
  void soundsys_init( void ){
    /* Proper code */
  }
  void soundsys_start( void ){
    /* Proper code */
  }
  void soundsys_stop( void ){
    /* Proper code */
  }

The sound system might be used elsewhere in the program like so:

  /* Using the procedural sound system */

  soundsys_init();           /* Init our sound system */
  /* Chunk of program code */
  soundsys_start();          /* Play a sound */
  /* Chunk of program code */
  soundsys_stop();           /* Stop playing sound */

The problem with this style of programming is it becomes messy. There are many functions exposed globally. Any variables that are to be shared between functions must also be created globally. A singleton is the object oriented method we use to wrap everything up nice and neat.

Required Ingredients

Creating a singleton in Javascript requires nothing more than an anonymous function and an object literal.

Object Literal

An object literal is nothing more than a comma-delimited list of name-value pairs enclosed in curly braces; the Javascript intepreter creates an object whenever an object literal is encountered. Separate names from values with a colon and don't forget to separate name-value pairs with commas.

  // Creating an object using an object literal, 1 property
  var obj1 = { prop : "Hello, World!" };
  alert(obj1);                         // Will display 'object'
  alert(obj1.prop);                    // Will display 'Hello, World!'

  // Creating an object with multiple properties
  var obj2 = { prop1 : "Hello, World!",
               prop2 : "Goodbye, World!" };
  alert(obj2.prop1);                   // Will display 'Hello, World!'
  alert(obj2.prop2);                   // Will display 'Goodbye, World!'

  // Creating an object with properties and methods
  var obj3 = { prop1 : "Some property",
               method1 : function(){
                 return this.prop1;
               }
             };
  alert(obj3.method1());               // Will display 'Some property'
Anonymous Function

An anonymous function is one which doesn't have a name; it may or may not be stored inside of a variable.

  // Creating an anonymous function and storing it in a variable
  var func = function(){
    alert("A function!");
  }

  // Calling the function
  func();                              // Will display 'A function!'

  // Creating an anonymous function and executing it on the spot;
  // notice the extra two pairs of open-close parentheses and the
  // semi-colon.
  (function(){
    alert("A function!");
  })();

It is the second anonymous function that is of most interest to us. It will be evaluated and called on the spot and there is no means of executing the function a second time. We don't have any reference to the function, either by name or through a variable.

Creating the Singleton

In order to create a singleton, we just return an object from the second anonymous function above.

  // Create a simple singleton
  var Singleton = (function(){
    var obj = {
      prop : "value";
    };

    return obj;
  })();

  // We've now created a singleton named 'Singleton'
  alert(Singleton);                    // Will display 'object'
  alert(Singleton.prop);               // Will display 'value'
Adding Constants

As it stands, our singleton isn't very interesting. Let's start by adding some internal "constants;" I use double quotes because they're not really constant.

  // Create a simple singleton
  var Singleton = (function(){
    var obj = {
      // "Constants"
      STATE_INIT  : 0x01,              // State initialize
      STATE_READY : 0x02,              // State ready
      STATE_ERROR : 0x04,              // State error
    };

    return obj;
  })();
Adding Properties

Typically you will need to keep track of values within your singleton; I like to prefix mine with an underscore.

  // Create a simple singleton
  var Singleton = (function(){
    var obj = {
      // The constants...

      // Properties
      _state : this.STATE_INIT,        // Set initial state
      _errmsg : null,                  // Current error message
    };

    return obj;
  })();
Adding Methods

Now we will add a couple of methods to our singleton.

  // Create a simple singleton
  var Singleton = (function(){
    var obj = {
      // The constants...

      // The properties...

      /**
       * getErrorMsg
       * Return the current error message
       */
      getErrorMsg : function(){
        return this._errmsg;
      },

      /**
       * clearErrorMsg
       * Clear the current error message
       */
      clearErrorMsg : function(){
        this._errmsg = null;
      }
    };

    return obj;
  })();
Complete Singleton

For reference, here is our complete example singleton.

  // Create a simple singleton
  var Singleton = (function(){
    var obj = {
      // "Constants"
      STATE_INIT  : 0x01,              // State initialize
      STATE_READY : 0x02,              // State ready
      STATE_ERROR : 0x04,              // State error

      // Properties
      _state : this.STATE_INIT,        // Set initial state
      _errmsg : null,                  // Current error message

      /**
       * getErrorMsg
       * Return the current error message
       */
      getErrorMsg : function(){
        return this._errmsg;
      },

      /**
       * clearErrorMsg
       * Clear the current error message
       */
      clearErrorMsg : function(){
        this._errmsg = null;
      }
    };

    return obj;
  })();
That's All Folks

So our example singleton isn't very useful, but I think it gets the point across. Hopefully you found this article helpful and can find some creative uses for singletons within your own applications.

Comments

Nice

Hi Robert, nice tut.

It's a bit weird to see a Singleton like this (some would argue that it's simply a global object reference), but then again, much JavaScript OO is a bit 'weird'... :P

Maybe you should add a little about private props?

Thanks

Hi John,

I wasn't aware you could create private properties in JavaScript; a quick search lead me to this:
http://www.crockford.com/javascript/private.html

As far as the global object reference, that's all it really is. But this method of instantiating and using the object is perfect for my uses.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options