Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

A guest post by Tim Ruffles, a Ruby & JavaScript developer based in London who teaches and mentors developers, and works on SidekickJS, a code-quality tracker for teams. Previously he was a front-end tech-lead for Skimlinks and Picklive; he talks about Javascript at conferences and events and can be reached at @timruffles.

Backbone’s model layer is minimal. Once you get to a certain level of complexity in Backbone.js, the concept of Value Objects can really clean up and simplify your code.

You’re already familiar with the concept of values. Values are things that are identifiable only by their value – numbers and strings are examples native to JavaScript. You don’t have an ‘instance’ of the number 7, with an id. All 7s are the same value, so they’re === each other.

Concepts we use in our model can also have this property. The 7th of July 1987 is a single concept, it’s non-sensical to have two ‘instances’ of it (oh, which 7th of July 1987 was that?). Everything involving time should be a value object. Points in space (lat,long; x,y) are another good example, as are amounts of money and measurements (like 7km – a number and a unit). You can probably think of a few in your own application.
NOTE: Talking about the model layer is a little confusing in Backbone as there is a class named ‘Model’. What I mean by model layer is the whole model of your domain consitituted by your applications’s models and collections. Read about decoupling Backbone.js applications here.

Another important part of values is that since values are entirely defined by their value, without an identity, they cannot be changed. For instance, adding 1 to 7 doesn’t change 7 into 8, it gives you a new value: 8. Likewise, you can’t add a day to the 7th of July 1987: you just start talking about a new date. Hopefully you can see why it would be a terrible idea to have a Number object with a set() method: anyone who already had a copy of a number might find it magically changed next time they used it!

Spotting potential values in Backbone

Do you have any values in your application already? Well a good indicator is when you’re listening to a few attributes changing on a model with the same handler. An even stronger one is if you’re using _.debounce or something similar, to avoid the handler firing multiple times when more than one of the attributes change at the same time. It’s then very likely that what you should be listening for is a whole new value – just like you wouldn’t listen for date.on("change:year change:month change:day"), you’d listen to change:date on the model that holds the date!

Adding values to Backbone

In Backbone.js, we have only Models to represent single concepts. Models have attributes that can all change. Values have attributes, but they cannot be changed. A date could be represented as new Backbone.Model({year: 1987, month: Month.JUNE, day: 7}), but we’d have the same problem I mentioned above if someone could simply change the year of our date!

So, we need a new tool to talk about values in Backbone. I think it’d be confusing if for most of our model layer we used get() to refer to a concept’s attributes. For values we used something else, so my implementation is used as follows:

So you can see how this implementation fulfills what we know about value objects, namely:

  1. They can’t be changed – you create new values instead.
  2. Two value objects of the same type are equal if their values are equal.

It can seem painful not to change a single field, but that’s easily solved via derive(). Simply give it any fields you’d like to change, and you’ll get a fresh value object with those values, taking any fields you’ve not specified from the original object.


To add additional comparison power to your values, you can define a valueOf method on your value objects. I’ve discussed this tip before, but in short it allows you to use inequalities (>, <, >=, etc.) with custom objects. Sadly, in JavaScript we can’t do the same with == or ===, which is why the eql() method is required. But with inequalities we can do useful things, like comparing Periods to see which has the longer duration.

Using values in Backbone

So how do we use value objects? We use them just as we’d use normal values in our application, just remembering to use eql() instead of === or ==. valueOf handles inequalities nicely.

One place you’ll probably want to add code is your Models’ parse() method, to turn nested objects into values. You’re probably already handling this kind of thing for nested Models, but here is a simple example:

Now we can immediately use any helpful methods we’ve added to point – perhaps add(vector) or distance(pointB). Any handler for a player’s position now simply listens to change:point, and never has to bother with _.debounceing: it gets a fresh Point every time.

Getting the library

I’ve released the above implementation of value objects for Backbone, but whichever you use, I hope the idea of value objects will help you make your Backbone code even more expressive!

Be sure to look at the Backbone.js resources that you can find in Safari Books Online.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

Developing a Backbone.js Edge incorporates the best practices and the techniques from the combined authors’ experience of developing many Backbone.js applications. In this book you get a complete guide to Backbone.js and equip you to start using the library straight away. While writing this book the authors developed an example app, called Hubbub, to illustrate the various features of the library.
Developing Backbone.js Applications shows you how to get the job done with Backbone.js. You’ll learn how to create structured JavaScript applications, using Backbone’s own flavor of model-view-controller (MVC) architecture.
Backbone.js Cookbook contains a series of recipes that provide practical, step-by-step solutions to the problems that may occur during frontend application development using an MVC pattern. You will learn how to build Backbone.js applications using the power of popular Backbone extensions and integrating your app with different third party libraries.

About the author

timruffles Tim Ruffles is a Ruby & JavaScript developer based in London. He teaches and mentors developers, and works on SidekickJS, a code-quality tracker for teams. Previously he was a front-end tech-lead for Skimlinks and Picklive. He talks about Javascript at conferences and events and can be reached at @timruffles.

Tags: Backbone, Backbone.js, Model Layer, Value Objects, Values,

Comments are closed.