When JavaScript first appeared on the scene way back in 1995, people were using it for fairly simple tasks such as form validation. These days, JavaScript has matured into a powerful language that, when coupled with HTML5 APIs like native video playback, drag-and-drop and the canvas
element, allows you to build detailed, interactive user interfaces for your websites.
However, as you start to use JavaScript to build larger and larger web apps with complex data structures and rich user interfaces, it becomes clear that the JavaScript language alone is not really up to the task. Interacting directly with the DOM starts to get messy and tedious; JavaScript doesn’t have much in the way of data manipulation functions; its object model can cause headaches; and its syntax can get overly fussy.
Fortunately, some great JavaScript libraries have sprung up in recent years to make your life as a web developer much easier. In this article I’m going to focus on five fairly recent libraries and technologies that are starting to gain traction:
- Backbone, for adding structure to large JavaScript-based web apps.
- Underscore, a utility-belt library that adds functional programming features to JavaScript.
- Knockout, a great way to simplify your user interfaces.
- Sugar, which extends the JavaScript language with a wealth of useful methods.
- CoffeeScript, a language that compiles down to JavaScript and is really nice to work with.
With each library, you’ll get an overview of what it does and how it works, and I’ve also included some useful links for finding out more information.
Ready? Let’s go!
Backbone: Adds structure to big apps
When you’re building simple JavaScript-enabled web pages, you can often get away with writing your JavaScript code from scratch. Build your page using HTML markup; add id
attributes to the elements you want to manipulate; then fetch the DOM elements using the JavaScript getElementById()
method.
For more complex pages, you’ll probably want to use a library such as jQuery to make it easier to grab an arbitrary bunch of elements in the DOM; manipulate those elements; and work with browser events such as page loads, clicks and keypresses.
Once you start writing big web apps, however, things can get messy as you manipulate DOM elements; manually track all the data in your app; link your data to your user interface; and deal with saving and reading the data on the server with Ajax calls and JSON.
At this point, you’ll benefit from using a JavaScript library that can provide some structure for your web app’s data, user interface, and functionality.
Backbone is one such library. It provides a set of tools that cleanly separate your app’s data and functionality from the user interface, and make it much easier to work with bunches of data and keep everything in sync with the web server.
Here are some of the key elements of Backbone:
- Models store your app’s data. Usually, a single Model object stores a single entity, such as a user, a tweet, or a forum post. With models, you can easily get and set data; validate the data automatically; save the data to a database on the web server; and retrieve a model’s data from the database. By default, Backbone communicates with the server using RESTful JSON requests. You can easily specify the URL format that a model should use when saving and retrieving data on the server.
- Collections let you manage groups of data that are stored in Models. You can add and remove Models in a Collection; retrieve models from a Collection; specify the sort order of Models in a Collection; fetch an entire Collection from the server, and so on.
- Views control how your data appears in the page. You associate a view with a DOM element, then set up the view so that it responds to certain events, such as a Model’s values being changed, and updates its DOM element accordingly. In this way, whenever any data in your app changes, the web page automatically updates to reflect the change. Nice!
- Routers map client-side URLs — created using either hashes like
#pageName
, or the new History API — to actions and events in your app. This allows your app to create bookmarkable, shareable URLs. For example, you can create a router that maps the URL/page/:pageName
to ashowPage
event, then create ashowPage
handler that accepts the value of:pageName
and displays the appropriate page. So when the user visits the URL/page/aboutUs
, yourshowPage
handler is automatically called and passed the valueaboutUs
. It can then display the “About Us” page.
Backbone is very lightweight and only has one hard dependency: Underscore, which you can use to manipulate Collections and create HTML templates that display data using Views. You can also include jQuery (or Zepto — see Honourable Mentions at the end of the article) to enable the RESTful persistence and history support, and to make it easier to access DOM elements in Views. Backbone also plays nicely with pretty much any other JavaScript library and templating system.
To learn more about Backbone, check out the official docs and take a look at this clearly-explained to-do list example.
Underscore: A utility-belt library
Underscore is written by the same folks that bring you Backbone. Its main purpose is to add support for functional programming to JavaScript. It provides lots of useful functions for working with collections, arrays, functions and objects, as well as some additional utility functions for things like templating and creating unique IDs. Essentially, Underscore fills in a lot of the gaps in the JavaScript language and makes it much easier to work with data, functions and objects.
The Underscore library is very small — around 3kB when minified and compressed — and it plays nicely with other JavaScript libraries like jQuery and Backbone.
Here’s just a sample of the functions that Underscore has to offer:
- Collection functions. These include
map()
that runs each value in a list through a function,reduce()
that uses a function to reduce a list to a single value,select()
for finding all values in a list that pass a specified test, andsortBy()
andgroupBy()
for sorting and grouping lists any way you like. - Array functions.
first()
,rest()
andlast()
let you easily extract slices from an array.compact()
removes all “empty” values from an array;flatten()
flattens nested arrays; andwithout()
lets you prune a set of values from a list. Other useful array functions includeunion()
andintersection()
for combining arrays;uniq()
for de-duping arrays; andzip()
for merging data that’s split across separate arrays. - Function-related functions. These include
bind()
andbindAll()
for binding functions to objects;memoize()
for caching function results; and lots of useful ways to call functions only when specific conditions are met, includingdefer()
,throttle()
,debounce()
,once()
, andafter()
. - Object-related functions. Underscore provides some functions that make it easier to work with objects, including
keys()
,values()
andfunctions()
for returning an object’s components;extend()
for inheriting objects;clone()
for copying objects; andtap()
for inserting arbitrary function calls within method chains. There’s also a range of useful testing functions likeisEqual()
,isEmpty()
,isElement()
,isArray()
, and more. - Utility functions. The last group of functions provide some miscellaneous features, including
times()
for running a function a given number of times, anduniqueId()
for generating GUIDs. A very useful function istemplate()
, which takes a template string and compiles it into a JavaScript function. You can then apply the template by calling the returned function, passing in a list of values to use in the template.
If you’re familiar with Prototype at all then you’ll no doubt recognize a lot of these functions from Prototype’s Array
, Enumerable
, Function
and Object
modules. As such, Underscore isn’t quite as useful if you’re already using Prototype. However, it’s perfect for augmenting other libraries such as jQuery. Unlike Prototype and Sugar, Underscore doesn’t extend the built-in JavaScript objects, preferring instead to create a separate suite of functions under the _
object (hence the name “Underscore”).
You can call Underscore functions in two different ways. For example, here are two ways to call the map()
function:
_.map( myArray, myFunction );
_( myArray ).map( myFunction );
The second approach allows you to chain methods together, which can help you write shorter, more elegant code.
The main Underscore documentation does a good job of explaining the library, and lists all the functions included in the library, along with plenty of examples.
Knockout: Simplifies your user interfaces
Like Backbone, Knockout is a library that helps you to structure your app and cleanly separate its data and behaviour (the model) from its user interface (the view). Knockout is simpler than Backbone and easier to get started with. It concentrates more on the link between the model and the view, whereas Backbone focuses more on manipulating the model and syncing the model with the server.
Knockout implements the Model-View-Viewmodel (MVVM) pattern, where a viewmodel is a JavaScript object that describes the data and behaviour of the user interface.
The essential idea is that you grab a data record from the server, load that data into a viewmodel, and add data-bind
attributes to your markup to bind the viewmodel to elements in the DOM. Once you’ve done that, the viewmodel and the DOM are in sync — if you update a value in the viewmodel, the corresponding element in the page automatically changes to reflect the new value. Conversely, if the user updates an element — for example, they type a new value into a text field — the corresponding value in the viewmodel updates automatically.
You can bind practically any DOM element or elements this way, from a text field through to a select menu and even — if you use the jQuery Templates that Knockout supports — an entire table of editable data.
Knockout is clever enough to track dependencies, too. For example, if you’ve created a text element in the page that takes its value from property a
in your viewmodel, and property a
is calculated using properties b
and c
, then whenever you update property b
or c
, Knockout updates both property a
and the text element automatically.
There’s a bit more to Knockout than this, but essentially it’s a very simple, elegant way to bind your app’s data to your view (web page), so that you never have to worry about manipulating the DOM directly. You just update the data in your viewmodel, and the web page updates automatically to reflect the changes.
The best way to learn Knockout is to use the excellent set of interactive tutorials on the Knockout site.
Sugar: Makes JavaScript’s native objects sweeter
Sugar is, in some ways, similar to Underscore, in that it’s a suite of tools that make working with JavaScript’s built-in objects — such as String
, Array
, and Object
— a more pleasant experience. You’ll find many of Underscore’s functions in Sugar too.
However, whereas Underscore focuses more on functional programming features, Sugar is more general-purpose, and also includes functions to manipulate strings and numbers; work with and format dates in very flexible ways; and make regular expressions a bit more programmer-friendly. It also fills in implementation gaps in certain browsers, allowing you to use modern JavaScript methods — such as indexOf()
, forEach()
and reduce()
— safely across all browsers.
Another key difference is that Sugar — like the Prototype library — provides its functionality by extending the built-in JavaScript objects. If this isn’t to your taste, and you prefer to keep JavaScript “clean”, then you’ll likely be drawn to Underscore’s more “hands-off” approach.
Here’s a selection of methods that Sugar adds to native JavaScript objects:
- String objects:
add()
for inserting characters into strings;camelize()
to convert C-syntax strings to camel case;chars()
for running a function on each character in a string;compact()
to trim a string and remove all whitespace within it;escapeHTML()
to convert HTML characters to entities;split()
for splitting strings using any separator; andstripTags()
to remove HTML tags. - Number objects:
format()
to format numbers with thousands separators and decimal points;hex()
to convert a number to hexadecimal; andordinalize()
to display an number’s ordinal equivalent (“1st”, “2nd”, etc.). - Array objects:
add()
for inserting elements anywhere in an array;average()
andsum()
for computing the average and total of a set of values;compact()
for removing empty values;each()
for running an iterator function over each element in an array;intersect()
andunion()
for combining arrays;map()
for mapping a set of array values to new values based on an iterator function;randomize()
to mix up the elements in an array, and a lot more besides. - Date objects:
create()
to create a Date object using practically any date format imaginable;addDays()
,addHours()
,addMonths()
and so on for easy date arithmetic;daysInMonth()
for finding the number of days in the date’s month;format()
for flexible date formatting; andis()
for comparing two dates with varying precision. - Object objects:
clone()
to copy an object (with optional deep cloning);each()
to iterate a function over an object’s properties;equals()
for comparing objects;fromQueryString()
to convert a URL query string to an object;isArray()
,isBoolean()
and so on for testing object types; andmerge()
for merging objects together. - Function objects:
after()
for creating a function that only runs after it’s been called a set number of times;bind()
for setting the value ofthis
within a function and for currying;debounce()
to stop a function being called too frequently due to a rapid series of events; anddelay()
andwait()
to create non-blocking function calls. - RegExp objects:
RegExp.escape()
escapes all regular expression tokens in a string (very useful), whileaddFlag()
,removeFlag()
andsetFlags()
let you manipulate a regular expression’s flags after the regular expression has already been created.
Sugar’s features page gives a good general overview of the library, while the easy-to-use API page covers each method in turn, along with examples.
CoffeeScript: A nicer way to write JavaScript
I’m cheating a little here, because CoffeeScript isn’t actually a library. Rather, it’s a language (and compiler) that you can use as an alternative to writing JavaScript. You write your code in CoffeeScript, then run the compiler to turn the CoffeeScript code into actual JavaScript code that your browser can run.
Why would you want to write your JavaScript code in a different language? Well, CoffeeScript is a very nice language that irons out a lot of the ugliness and quirks of JavaScript. It can even make your code run a bit faster by optimizing the JavaScript that it generates.
Since it’s essentially just JavaScript, CoffeeScript works seamlessly with all other JavaScript libraries like jQuery, Prototype, Dojo, Backbone and Knockout.
CoffeeScript borrows a lot of the syntactic sugar from languages like Ruby and Python, so if you’re familiar with those languages then you’ll be right at home with CoffeeScript. Here are some of the headline features of the CoffeeScript language:
- A cleaner syntax. CoffeeScript does away with many of the parentheses and braces that tend to litter JavaScript code. For example, you can create
if/else
blocks, loops, functions and objects using indentation, rather than braces. You can also add newlines for readability when creating arrays and long strings. - Functions are easy to create with the
->
operator. They implicitly return values, and you can supply default argument values easily, as well as splats (variable numbers of arguments). - Comprehensions let you easily loop over arrays and objects. For example, to run the function
eat()
for each item in an array, you can simply writeeat food for food in ['toast', 'cheese', 'wine']
. - Easy array slicing and splicing. You can use ranges to pull a slice from an array easily — for example,
mySlice = myArray[3..8]
. You can also assign values to an array range, letting you splice easily. - The existential operator,
'?'
. This behaves like Ruby’snil?
operator, giving you a nice way to check for a variable’s existence. - Classes. JavaScript’s prototype-based object model is very powerful, but it can be tricky (and sometimes awkward) to work with. CoffeeScript makes life a lot simpler by adding the
class
,extends
andsuper
keywords, as well as constructors. This lets you build your objects using a class-based approach, and greatly simplifies the code you need to write. - String interpolation and heredocs. CoffeeScript allows Ruby-style string interpolation, like this:
myString = "My variable's value is: #{ myVar }"
. No more endless concatenating of strings and variables with the+
operator! You can also use heredoc syntax to insert large chunks of formatted text, much like you can in Perl, PHP and other languages.
The standard way to install the CoffeeScript compiler is using Node.js and npm. You’ll find full instructions in the CoffeeScript docs. Alternatively, if you just want to play around with CoffeeScript, you can click the Try CoffeeScript menu option on the CoffeeScript site and just start typing!
Honourable mentions
There are many other fantastic JavaScript libraries out there that, for one reason or another, didn’t quite make it into this list. Here are some that you might like to check out:
-
- Zepto is a very lightweight library for mobile sites and apps that aims to provide a jQuery-compatible API for a fraction of the download size. It does this by only supporting WebKit browsers (as used by iOS and Android), and skipping a lot of jQuery features that aren’t needed on mobile devices, such as IE6 support. “jQuery Lite for mobiles”, if you like.
- jCanvaScript and oCanvas give you nice object-oriented interfaces for working with the
canvas
element, including drawing shapes and animation. - Mapstraction is an abstraction library for a range of common mapping services, including Google Maps, OpenStreetMap, Yahoo! and Microsoft. This makes it easy to choose from, or switch between, mapping providers.
- ClojureScript is similar to CoffeeScript, except that it’s based on the Clojure dialect of the Lisp language.
- php.js is a (brave!) effort to implement most of PHP’s built-in functions in a JavaScript library. So far it’s looking pretty good, with most commonly-used PHP functions ported.
- iScroll is handy if you’re developing mobile web apps. It gives you a way to have a scrollable content area in the page, along with a fixed header and/or footer — something that isn’t currently possible to implement natively with most mobile browsers. It also provides some other nice features such as pull-to-refresh, pinch-to-zoom and custom scrollbars.
- pdf.js aims to implement an entire PDF viewer/renderer in JavaScript. While it’s still in early development, it’s already pretty impressive, as you can see in this demo.
Summary
In this article, you’ve looked at five recent JavaScript libraries and technologies that can help you write JavaScript apps more quickly and effectively:
-
-
- Backbone, which provides a set of objects to help you structure your app’s data in a manageable way, as well as cleanly separate your data from your user interface.
- Underscore, a nice library that adds a large number of functional programming features to JavaScript, making it much easier to work with data, functions and objects.
- Knockout, an implementation of the Model-View-Viewmodel (MVVM) pattern, which gives you a really clean way to link your app’s data to its user interface, and puts an end to tedious DOM manipulation.
- Sugar, which extends the core String, Number, Array, Date, Object, Function and RegExp objects in order to fill some of the gaps in JavaScript, such as powerful string manipulation, number formatting and flexible date handling.
- CoffeeScript, a compact, easy-to-write language that compiles down to JavaScript and adds a lot of great features, such as comprehensions, array manipulation and some really nice object-oriented syntax.
-
Many of these libraries work well together, and with other libraries — for example, you can happily use Backbone, Underscore and jQuery together on the same page, giving you a powerful set of libraries with which to build your websites and web apps.
You also looked at some other up-and-coming libraries that can make your JavaScript coding life easier.
I hope you enjoyed this article, and that it’s inspired you to go off and learn a few of these fantastic technologies. Thanks for reading!
What’s your favourite JavaScript library or technology, and why? Let us know in the comments below!
Leave a Reply