JasonWyatt

This blog is full of stuff, and things.

Find my resume.

permalink

Anonymous Classes with JavaScript and Self-Calling Functions

I was messing around with Firebug today, trying to test out a concept for event handling and I didn’t want to have to go through all the pomp and circumstance of creating a legitimate class in the firebug console so I dreamed up a way to make an anonymous class. Here’s what I came up with: (I left out the event handling stuff)

var a = new (function(name){
    this.sayHello = function(){
        console.log("Hello, ", name, "!");
    };
})("Jason");

a.sayHello();

What’s going on here? Remember that classes in JavaScript are just functions that can be called with the new keyword to instantiate a new object of the class defined by that function. (the function acts as the class’s constructor) So, we’re setting a variable, a, to a new instance of a class whose constructor is an anonymous function wrapped in parentheses to encapsulate it.

We can take this concept even further by working with our anonymous class’s prototype after we instantiate it. However, I cant really think of a practical reason to do this other than to make the code prettier, if you know - leave a comment.

var a = new (function(name){
    this.name = name;

    this.sayHello = function(){
        console.log("Hello, ", this.name, "!");
    };
})("Jason");

a.constructor.prototype.sayGoodbye = function(){
    console.log("Goodbye, ", this.name,".");
};

a.sayHello();
a.sayGoodbye();

Why do I care?

Anonymous classes can be useful for things like mock objects in the case of unit tests. Imagine that you have a unit test which checks that a static method called serialize() correctly serializes an instance of its class, MyClass to a JSON string. We don’t really want to create a new instance of the real class if we only need to check that certain attributes are correctly serialized. Check it out:

/* 
 Lots of code to describe MyClass
 */
MyClass.serialize = function(instance){
    return JSON.stringify({
        name: instance.getName(),
        longList: instance.getList()
    });
};

/*
 In another file, for our unit test...
 */
function testSerialize(){
    var data = {
        name: "Awesome object.",
        longList: [1,2,3,4]
    };

    var actualResult = MyClass.serialize(new (function(settings){
        this.getName = function(){
            return settings.name;
        }
        this.getList = function(){
            return settings.longList;
        }
    })(data));

    assertEqual(JSON.stringify(data), actualResult);
}

I realize that this probably isn’t all that novel, but it’s an example of how JavaScript is a great language for allowing programmers to be creative.

blog comments powered by Disqus