A bit of technology

news, thoughts, articles and a bit of fun!

Proper singleton in JavaScript

, , , ,

I've seen a lot of articles about singletons in JS all over the web, but most of them suck, because people writing them do not know JS well enough. Even Wikipedia's examples are no good. Let's make a list of singleton "features".

  1. It is usable like any other object.
  2. Singleton is always the same no matter where it is called from.
  3. User can not create another instance of singleton.
  4. It can store some private data and have some private methods.

The simplest way to create singleton in JavaScript is to use JSON:

var Singleton = {
    data: 'Hello, world!',
    print: function() {
        alert(Singleton.data)
    }
}

Looks good and easy, right? Every object created by JSON automatically becomes singleton in JavaScript, because it does not have any constructor and can not be instantiated anywhere except for JSON statement. But this solution has one problem... Click "Read more" — a lot of text is coming your way smile
Flattr this

The problem I'm talking about is that this way you can not have any private data and methods which means such objects are more like name spaces — not exactly what we want.

There is no such thing as private data in JavaScript, but you can freely create hidden methods and variables inside functions. Internal data is only visible inside the function it is created in. Another great feature we have in JavaScript is anonymous functions. So we can wrap "private" data and methods inside anonymous function, define our JSON singleton inside this function and throw a "pointer" to singleton to outer world. Look at the example:

var Singleton = // It will hold our singleton, don't forget "=" character :)

(function() { // Creates and runs anonymous function, its result is assigned to Singleton

    var privateData = 'Hello, world!' // Any variable inside function becomes "private"
    var counter = 0

    function processData() { // Any function becomes "private" too!
        counter++
    }

    var instance = { // This is a definition of our Singleton, it is also private, but we will share it later
        print: function() { // This will be our public method
            processData()
            alert(privateData + ' Called print() ' + counter + ' times.')
        }
    }

    return(instance) // And some simple magic - global variable Singleton transforms into our singleton!

})()

Now you can access your singleton using Singleton name. Just like that:

Singleton.print()

But why do examples from Wikipedia suck? First one is not a kind of singleton we want. I've already explained that. The second one suck because it has performance issues. On the other hand it provides lazy-loading and can be useful if that feature is a must.

So now you know the only correct way to implement singleton pattern in JavaScript with all the bells and whistles, without compromises, bugs and performance issues. Easy and effective smile

I hate Opera 10.60!Bike-trip to Sigulda 2010

Comments

Unregistered user Wednesday, August 11, 2010 12:44:36 PM

esneko writes: круто! оказывается этот приём называют модульный шаблон. только ты не упомянул ещё возможность импортировать глобальные переменные в этот объект, передавая их через параметры анонимной функции, а также способ обращаться из публичных методов друг к другу и публичным переменным данного объекта через this.

Unregistered user Saturday, July 23, 2011 12:15:52 AM

JAX writes: Where is the specification that states a Singleton must store private data? No where... All a singleton implies is that only one instance of the object can exist.. That is it... Wikipedia's definitions are fine. All you did was use closure to create private properties... That has nothing to do with singletons...

Write a comment

New comments have been disabled for this post.