Arjan van der Gaag is a thirtysomething software developer,
historian and all-round geek. This is his blog about Ruby, Rails,
Javascript, Git, CSS, software and the web. See more projects or
follow Arjan at
Github,
Twitter,
LinkedIn or via his feed.

The Javascript Class Pattern

Written on
03 oct 2011
and tagged
javascript

Some of the worst code I have ever written was in Javascript, back when I was less interested in prototypal inheritance and closures than in scrolling text in browser status bars. But Javascript is an awesome language, once you ‘get’ how it works.

One of my main problems with writing anything non-trivial in Javascript is code organization. Javascript does not come with any organization structures out of the box, like Ruby provides classes and modules. But in Javascript, you can simply create your own. Here’s a recipe I’ve learned over the years, and have seen popping up all over the web – not least in Coffee script. It provides a simple convention for creating ‘classes’ in vanilla Javascript. Here’s an explanation of how it works.

The constructor function

The most important part is the actual object that represents our class: the constructor function. This is the function you will invoke with the new keyword to create a new instance.

functionMyClass() {}
var instance = new MyClass();

Behind the scenes, the following is happening:

Create a new object.

Execute the constructor function in the context of that object – e.g. in the constructor function this refers to the new instance.

Give the new object a constructor property, referring to the MyClass function.

The body of the constructor function is the initializer method, that should take care of setting up a valid object. You can use it to assign properties to the new instance:

But it would be inefficient for every instance of our class to contain a new copy of this method. What’s more, we can no longer change the method for all instances – we can only modify individual objects.

We would like all instances to share the same method. This is where the prototype comes in. Every object keeps a reference to its prototype, which is just another object. The prototype property is used in property lookup: when asking an object for the value of a property, javascript first looks at the object’s own properties. When the object itself does not have a property by the given name, javascript will ask its prototype object for the property. The prototype may delegate the request to its own prototype, creating a prototype chain of objects where properties can be found in.

Because multiple objects can share a single object as their prototypes, we can define properties on the prototype of our class and have them shared among all instances of our class. Since a function is just an object, we declare our prototype properties on the constructor function itself:

Now our program has only a single copy of the greet function, while many instances can use it. Note that this refers to the current object in the prototype function, not the prototype object it has been defined on. So we could use it to define and access instance properties:

Note that the prototype properties can hold any value you like – not just functions.

Property visibility

Javascript does not support property visibility. When you have an object, you can read and write all its properties – there are no keywords like private or public. This is not a problem, but if you want to, you can feign private properties using closures.

A closure is simple: it is an execution context that knows about its surroundings, but does not export its contents. So a closure can access variables in the same context as it itself has been defined, but variables defined inside the closure are not accessible outside the closure.

Here, we define our class in an anonymous function, that is immediately executed. The function returns our class (the constructor function) into the outer variable MyClass. Note how inside the class definition the variable multiplier exists. We can use it in the constructor function, because the MyClass function knows about its surroundings. But our anonymous function does not export anything to its surrounding apart from what is explicitly returned. It only returns the MyClass function, so outside the closure multiplier does not exist.

An added benefit is that the wrapping closure function is a neat way of organizing our entire class definition into a single block of code.

Inheritance

To make one class inherit from another class, we could simply assign the parent class as the prototype object of the child class. Normal javascript property lookup will then try to find properties in the child class, and then up the prototype chain into the parent class. The effect is that the child class inherits all the properties of the parent class. It looks good. But note what happens when we do that:

Note how changing properties of c also changed the property in p: it is actually the very same property. That is no good, so we need to do better.

We can solve this problem by creating an intermediary prototype, a ghost object that no one knows about. This ghost object will share its prototype with the Parent, so it shares all properties of the Parent. But when we set the prototype of Child to an instance of our new ghost class, changing a prototype property on Child will trigger a change in that single instance, and not its protype. Hence, the original Parent prototype remains intact.

To get this to work, we need a helper function that takes care of the heavy lifting for us:

There is one problem: if we ask an instance of Child about its type using instanceof, it will tell us it’s an instance of ghost, not of Child. We don’t want that. Luckily, we can explicitly set what should be considered the constructor function in our object:

Accessing the parent class from the child class

When a child class does not implement a property, it will be looked for in the parent class. That’s how inheritance works. But when we do implement it in the child, the parent function is completely sidestepped. How can we (easily) access that function?

We need to set a special property on our child class that refers to the original parent’s prototype. We’ll do that in our inherits function:

By setting the _super property, the child class can now access its conceptual parent’s properties (remember, the technical ‘parent’ is the ghost object!) using the _super property on the constructor function.

Note that we explicitly name the Child class to access its _super property. We could use a slightly more obscure but flexible way:

this.constructor._super.constructor.call();

Class properties

Our _super property has introduced us to what you could call class properties, or ‘static’ properties. Remember, a function is just an object, so we can assign properties on it. So Child._super is a single property available on a single object, our Child ‘class’ (i.e. constructor function).

In order to implement a no-surprises inheritance model, we need to make sure child classes inherit these properties as well from their parents. We simply need to copy any property of the parent constructor function to the child constructor function. Easy enough:

Note how we check if the property is actually defined on the parent constructor function itself, and not in its prototype chain. This helps us not override existing, native function properties such as length.

Bonus: mixins

Copying the properties from one object to another sounds a lot like another incredibly useful idiom: mixins. Mixins allow us to add properties to an object, without implying a ‘kind of’ relationship.

A good example of this would be the observer pattern. We could want to have multiple objects with the capability to accept observers and trigger events, but there is no such thing as an ‘observable’ object – being observable is a trait, not an identity.

Mixing in one object into another is what we’re doing when we’re copying class properties from the parent to the child, so we can abstract that into a separate function a re-use it:

This allows us to enhance an individual object with new properties. Such a collection is usually called a module, but in javascript it is just another object. Say we have a module for making any object capable of saying ‘Hello, world!’:

var hello_module = {
speak: function() {
alert('Hello, world!');
}
};

We could mix this into any object we’ve got individually:

var inst = new MyClass();
mixin(inst, hello_module);

Since our constructor function prototype is also just an object, we could mix it into that to have the module mixed into any instance of our class:

Bonus 2: binding

One problem I often experience when trying to do object-oriented javascript with jQuery, is that jQuery likes to bind event handlers to their DOM elements. More abstractly, Javascript allows you to change the execution context functions are called in. This can be very useful – as with prototype functions executing in the object’s context – but you could run into trouble when your method loses access to its object state.

The solution is to bind a function to a particular context. This is easily done with a little helper function:

The bind function gives us a new function, that when called, calls the original function we passed in, in the context of the original context we passed in. Any arguments are simply passed along with the arguments object.

When initialising a new object, we simply override a prototype method on our new object with a copy of that method bound to the context of that new object we’re creating.

Using bind, our object methods can no longer be ripped out of context and can be safely used as jQuery event handlers.

Wrap-up

So, with only three helper methods and some convention, we have built a fully-functional class system, including inheritance, private properties, mixins and bindings. This should make a great starting point for any Javascript program.

Drop these into your script somewhere and you’re ready to go (I’ve actually created a little library called OO.js with these functions for easy re-use). Here’s a quick example of all the features discussed here:

Then, it will throw an exception as there is no warn property defined on the f object – it is defined as a private function inside the class closure.

I have found this pattern to be very useful for organizing my javascript code. It enables clean object-oriented design – not least because of mixins – and is simple enough to not need any complex helper functions for defining classes. It is all just plain, vanilla javascript with three helper methods.

You cannot leave comments on my site, but you can always tweet questions or comments at me: @avdgaag.