JavaScript

An Introduction To Underscore.js

Recently I starting working in the Backbone.js framework which has dependency on the Underscore.js framework. Underscore is a JavaScript utility library with many useful functions to handle common programming use cases.

I decided it would be a good idea to spend some time discovering what all the framework has to offer those within and outside of Backbone. In this blog, I discuss some of the more useful functions I have found inside of Underscore.

_.each

You can use _.each to make more easily readable loops. Here is a common way to loop through an array in JavaScript:

var list = [1 , 2 ,3];
for(var i = 0; i < list.length; i++ ) {
    console.log(list[i] * 2); //logs ‘2, 4, 6’
}

Using underscore’s _.each, we can make this much more readable, mainly as you are not having to use access the items of the array with the index.

_.each(list, function (item, index, list) {
	console.log(item * 2);//logs ‘2, 4, 6’
});

_.map is similar, but returns an array built from the outputs of the function.

var result = _.map(list, function (list, function (item, index, list) {
    return item * 3;
})); 
console.log(result);//logs ‘[3, 6, 9]’

_.filter

This does what you can probably guess by its name: filters a collection. It loops through a collection and returns an array of entries that return true for a truth test.

var result = _.filter(list, function (item) { return item % 2 == 1 }); 
console.log(result);// logs '[1,3]'

_.times

This is a very simple way to loop a specific number of times.

_.times(5, function () {
    console.log('hello');// will log hello 5 times
});

_.pluck

This is a convenient way for pulling out a list of property values from a list of objects.

A fairly common task in coding might be getting a list of names from a collection of people objects. Here is a way of doing this in JavaScript:

var people = [{
    name: 'John',
    age: 30,
    state: 'KS'
}, {
    name: 'Phil',
    age: 25,
    state: 'KS'
}, {
    name: 'Bob',
    age: 50,
    state: 'NY'
}];
var names = people.map(function(person) {
    return person.name
});
console.log(names); // logs '["John", "Phil", "Bob"]'

This can be simplified with Underscore to:

var names = _.pluck(people, 'name');
console.log(names);// logs '["John", "Phil", "Bob"]'

_.findWhere

This can used to find a single object from a collection that matches the given key-value pairs. First I’ll write something similar using just JavaScript:

var person;
for (var i = 0; i < people.length; i++) {
    if (people[i].name === 'Phil' && people[0].state == 'KS') {
        person = people[i];
    }
}
console.log(person); //logs '{name: "Phil", age: 25, state: "KS"}'

Now see it simplified with Underscore:

var person = _.findWhere(people, { name: 'Phil', state: 'KS' });
console.log(person);//logs '{name: "Phil", age: 25, state: "KS"}'

Not only is the code more simple to write, but notice how much more apparent it is to the reader what the code is actually trying to accomplish.

_.where

_.where is similar to _.findWhere, but will return an array of all matching entries instead of just the first one found.

var kansasPeople = _.where(people, { state: 'KS' });

_.sortBy

Sorting collections by property name can done with _.sortBy.

var sortedPeople = _.sortBy(people, 'age');
console.log(_.pluck(sortedPeople, 'name'));//logs '["Phil", "John", "Bob"]'

Backbone leverages its dependency on Underscore so that Backbone collections can inherently use many of the underscore iteration functions such as each, map, findWhere, Where, Filter, sortBy, etc. These prove quite useful and powerful when dealing with large data collections.

There are multiple type checking methods and are super simple to read and understand that can come in handy.

_.isString(object);
_.isNumber(object);
_.isBoolean(object);
_.isDate(object);
_.isNan(object);
_.isNull(object);
_.isUndefined(object);

Underscore can even be used to template strings. This is useful for creating html templates with objects.

var helloTemplate = _.template(
    '<h1>Hello <%= name %></h1>');
var htmlString = helloTemplate(people[2]);
console.log(htmlString); //'<h1>Hello Bob</h1>'

You can write JavaScript logic within templates, like in the following example. This would produce an unordered list of all the people in the person array.

var listTemplate = _.template(
    '<ul><% _.each(people, function (person) { %>' +
    '<li><%= person.name %></li>' +
    '<% }) %></ul>

');
var htmlListString = listTemplate({
    people: people
});

Final Thoughts

These were some pretty simple examples of what can be found in the Underscore framework. Some of the benefits are less apparent in smaller and simpler code chunks. But, as the complexity of the code increases, this is where Underscore really shines as the useful toolbox that it is.

Using the framework can allow you to be more expressive in your code, improving readability for all those that may have to eventually dig through your code.

There are many other functions Underscore.js has in its library. You can read more about the rest of them at http://www.underscorejs.org.

Reference: An Introduction To Underscore.js from our WCG partner Nick Brown at the Keyhole Software blog.

Nick Brown

I am a web application developer based out of Overland Park, KS. I have experience with .NET and developing single page applications with JavaScript. When I'm not coding, you can find me playing guitar, or being a father to my three children.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button