Getting Cozy With Underscore.js

Getting Cozy With Underscore.js

Tutorial Details
  • Applications Used:Underscore, JavaScript
  • Difficulty: Intermediate
  • Completion Time: 30 minutes

As JavaScript is slowly moving out of the browser, several tools have emerged that significantly improve JavaScript’s robustness.

One such tool is called Underscore.js and that’s what we’re going to take a look at today. Let’s get started!


Meet Underscore.js

So what exactly does Underscore do?

Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects.

One of the nicer things about working in Python or Ruby are the fancy constructs like map that make life a lot easier. The current version of JavaScript, sadly, is fairly barebones when it comes to low level utilities.

As you read above, Underscore.js is a nifty little JavaScript library that brings in a ridiculous amount of functionality at a mere 4kb.


Underscore in Action

“Enough yapping about the library”, I can hear you say. Right you are! Let’s take a look at Underscore in action first before I resume my yapping.

Let’s assume you have a random array of test scores and you need a list of those with 90+ score. You’d usually write up something like so:

var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42], 
topScorers = [], scoreLimit = 90;

for (i=0; i<=scores.length; i++)
{
	if (scores[i]>scoreLimit)
	{
		topScorers.push(scores[i]);
	}
}

console.log(topScorers);

It’s pretty simple and even with optimization, it’s fairly verbose for what we’re trying to do.

Let’s look at what we can achieve with Underscore next.


var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42], 
topScorers = [], scoreLimit = 90;

topScorers = _.select(scores, function(score){ return score > scoreLimit;});

console.log(topScorers);

I don’t know about you but I just had a nerdgasm. That’s some incredibly concise and readable code right there.


Sweet but Do I Really Need This?

Well, it all depends on what you’re trying to do. If your use of JavaScript is limited to merely playing around with the DOM, then the answer is mostly no since jQuery does most of what you’d want to do.

Yes.

On the other hand, if you’re dealing with non-DOM code or even complex, think MVC, front end code, Underscore is an absolute boon.

While some of the functionality exposed by the library is slowly making its way into the ECMA specifications, it’s not available in all browsers and making your code work cross browser is another nightmare on its own. Underscore provides you with a nice set of abstractions that work everywhere.

And if you’re a performance oriented person, as you should be, Underscore falls back to native implementations, if available, to make sure performance is as optimal as possible.


Getting Started

Just grab the source here, include it in your page and you’re good to go.

If you were expecting a big set up process, you’re going to be sorely disappointed. Just grab the source here, include it in your page and you’re good to go.

Underscore creates and exposes all its functionality via a single object, in global scope. This object is the titular underscore character, _.

If you’re wondering, yes, this is quite similar to how jQuery works with the dollar [$] symbol. And just like jQuery, you can remap this character in case you run into conflicts. Or if you’re like me and have an irrational love for the tilde.


Functional or Object Oriented?

While the official marketing blurb for the library states that it adds functional programming support, there is actually another way of doing things.

Let’s take our earlier code as an example:


var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42], topScorers = [], scoreLimit = 90;

topScorers = _.select(scores, function(score){ return score > scoreLimit;});

console.log(topScorers);

This method above is the functional, or procedural, approach. You can also use a more straightforward, probably more apparent, object oriented approach.


var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42], topScorers = [], scoreLimit = 90;

topScorers = _(scores).select(function(score){ return score > scoreLimit;});

console.log(topScorers);

There is no real ‘right’ way to do things but keep in mind that you can jQuery-esque method chaining with the latter method.


Checking Out the Functionality

Underscore provides a little more than 60 functions that span a number of functionalities. At their core, they can be classified into groups of functions that operate on:

  • Collections
  • Arrays
  • Objects
  • Functions
  • Utilities

Let’s take a look at what each does and if applicable,one or two of my favorites from each section.


Collections

A collection can either be an array or an object, an associate array in JavaScript if I’m to be semantically correct.

Underscore provides a lot of methods that operate on collections. We saw the select method earlier. Here are a few more incredibly useful ones.

Pluck

Let’s say you have a nice little array containing key value pairs and you’d like to extract just a specific property from each. With Underscore, it’s a cinch.


var Tuts = [{name : 'NetTuts', niche : 'Web Development'}, {name : 'WPTuts', niche : 'WordPress'}, {name : 'PSDTuts', niche : 'PhotoShop'}, {name : 'AeTuts', niche : 'After Effects'}];
var niches = _.pluck(Tuts, 'niche');

console.log(niches);

// ["Web Development", "WordPress", "PhotoShop", "After Effects"]

Using pluck is as simply as passing in the target object or array as well as which property to pick out. Here, I’m merely extracting the niche for each site.

Map

Map creates an array from a collection where each element can be mutated or otherwise changed through a function.

Let’s take the earlier example and extend it a bit.


var Tuts = [{name : 'NetTuts', niche : 'Web Development'}, {name : 'WPTuts', niche : 'WordPress'}, {name : 'PSDTuts', niche : 'PhotoShop'}, {name : 'AeTuts', niche : 'After Effects'}];

var names = _(Tuts).pluck('name').map(function (value){return value + '+'});

console.log(names);

// ["NetTuts+", "WPTuts+", "PSDTuts+", "AeTuts+"]

Since I noticed the names missing the plus sign at the end, I’m adding them in the extracted array.

You’re not limited to simple concatenation here. You’re free to modify the passed value to your heart’s desires.

All

all is useful if you need to check every value in a collection passes a certain criteria. To check whether a student has passed in every subject, for example.


var Scores = [95, 82, 98, 78, 65];
var hasPassed = _(Scores).all(function (value){return value>50; });

console.log(hasPassed);

// true


Arrays

Underscore has a bunch of functions that work exclusively on arrays which is highly welcome since, compared to other languages, JavaScript provides awfully few methods dealing with arrays.

Uniq

This method basically parses an array and removes all duplicate elements providing you with only unique elements.


var uniqTest = _.uniq([1,5,4,4,5,2,1,1,3,2,2,3,4,1]);

console.log(uniqTest);

// [1, 5, 4, 2, 3]

This comes in extremely handy when you’re parsing huge datasets and need to weed out the duplicates. Keep in mind that only the first instance of an element is counted so the original order is kept.

Range

An extremely handy method that lets you create a ‘range’ or list of numbers. Let’s look at a super quick example.


var tens = _.range(0, 100, 10);

console.log(tens);

// [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

The method’s parameters are, in order, starting value, ending value and step value. If you’re wondering, using a negative step value leads to a decrementing range.

Intersection

This method compares two arrays to each others and returns the list of elements that are found in all of the passed arrays i.e. an intersection in set theory.

Let’s extend the earlier example to see how this works.


var tens = _.range(0, 100, 10), eights = _.range(0, 100, 8), fives = _.range(0, 100, 5);

var common = _.intersection(tens, eights, fives );

console.log(common);

// [0, 40, 80]

Easy, right? You just pass in the list of arrays to compare and Underscore does the rest.


Objects

In addition to the fairly expected is checks, Underscore provides various methods to clone, extend and other manipulate objects.

Here are a few of my favorites.

Keys and Values

Have a massive object where you need only the keys or only the values? It’s so darn easy with Underscore.


var Tuts = { NetTuts : 'Web Development',  WPTuts : 'WordPress',  PSDTuts : 'PhotoShop', AeTuts : 'After Effects'};
var keys = _.keys(Tuts), values = _.values(Tuts);

console.log(keys + values);

// NetTuts,WPTuts,PSDTuts,AeTutsWeb Development,WordPress,PhotoShop,After Effects

Defaults

This method is quite useful when you need to create objects with sensible defaults when one might not be used when creating it.


var tuts = { NetTuts : 'Web Development'};
var defaults = { NetTuts : 'Web Development', niche: 'Education'};

_.defaults(tuts, defaults);

console.log(tuts);

// Object { NetTuts="Web Development", niche="Education"}


Functions

As wonky as it sounds, Underscore has functions that work on functions. Most of the functions tend to be fairly complicated to explain here, so we’ll take a look at the simplest.

Bind

this is an elusive part of JavaScript and tends to leave a lot of developers really confused. This method seeks to make it a bit easier to tackle.


var o = { greeting: "Howdy" }, 
	f = function(name) { return this.greeting +" "+ name; };

  var greet = _.bind(f, o); 

  greet("Jess")

It’s a bit confusing so stay with me here. The bind functions basically lets you keep the value of this whenever and wherever the function is called.

This is specially useful when you’re working with event handlers where this is hijacked.


Utilities

And to further sweeten the deal, Underscore provides a ton of utility functions. Since we’re fairly out of time, let’s just look at the biggie.

Templating

There are already a ton of templating solutions out there but Underscore makes its solution worth a look by being fairly tiny in its implementation whilst being fairly powerful.

Let’s take a look at a quickie example.


var data =   {site: 'NetTuts'}, template =   'Welcome! You are at <%= site %>';

var parsedTemplate = _.template(template,  data );

console.log(parsedTemplate);

// Welcome! You are at NetTuts

First up, we create the data to populate the template followed by the template itself. By default, Underscore uses ERB style delimiters though this is entirely customizable.

With those in place, we can simply call the template passing in our template and the data. We store the result in a separate string to be used later to update content, as needed.

Keep in mind that this is an extremely simple demonstration of Underscore’s templating. You can find use any JavaScript code inside the template using the <% %> delimiters. When you need to iterate over complex objects, say JSON sources, you can pair up with Underscore’s excellent collection functions to create templates rapidly.


Still Not Convinced That You Should Pick This

jQuery and Underscore go hand in hand.

No, no, you’ve got it all wrong! If anything, jQuery and Underscore complement each other well and go hand in hand. Really!

See, jQuery does a few things extremely well. DOM manipulation and animation are chief amongst those. It doesn’t deal with anything in the higher or lower levels. If frameworks like Backbone or Knockout deal with the higher level issues, Underscore tackles all the relatively bare metal ones.

For even more perspective, jQuery has little purpose outside the browser as the bulk of its functionality deals with the DOM. Underscore, on the other hand, can be used on the browser or on the server side without any issues. In fact, Underscore has the most number of Node modules dependent on it.

Well, that’s about it for today. Considering the scope of Underscore, we’ve barely scratched the surface here. Make sure to check out more of the library and let me know if you have any questions in the comments below. Thank you so much for reading!

Siddharth is Siddharth on Codecanyon
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • pixelBender67

    Love this library !

  • pixelBender67

    Love this library !

  • tony

    this is returning an empty []

    var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42], topScorers = [], scoreLimit = 90;

    topScorers = _(scores).select(function(score){ return score > scoreLimit;});

    console.log(topScorers); // []

    • Orijit

      Are you sure you have included Underscore.js properly? Coz I copy pasted your code into my console and it returned [99, 91, 95]

  • http://www.udgwebdev.com Caio Ribeiro Pereira

    It look like very useful this Underscore.js, Is there a node.js version too?

    • http://twitter.com/connor Connor Montgomery

      Yep – _.js works great in a Node environment, as well as a client-side environment.

  • Nykeri

    At first i admint i was like ‘pffft’ but after reading this i was l ike ‘God damn…’. Some of the features this library offers should be built into JS becuase they are just plain simple, concise, readable and awesome

    • Abhijit

      I agree. Underscore does the job nicely, but it’s still plain JavaScript behind the scenes. Hopefully at least some of these features will get native implementations in near future.

  • ball6847

    more js productivity

  • Akaryatrh

    Frankly, underscore rocks. I especially love the _.isEqual function that makes json object comparison.

  • hardevine

    jquery’s serializeArray() return array of objects having { name value pairs}..
    is there any underscore method which would take above and return single object having name & value as key-value pairs..

    var formd = $(‘form’).find( ‘:hidden,:radio,[type=number],:input’ ).serializeArray();

    var formObj = {};
    $.each( formd, function ( i, el ) {

    el.value = ($.isNumeric( el.value )) ? parseInt( el.value ) : el.value;
    formObj[el.name] = el.value;
    } );
    return formObj;

    like….
    var formdata = _.formToObj(‘#formid’);

    • http://28inch.co.uk 28inch

      Try this instead of serialize array:

      $.fn.serializeObject = function()
      {
      var o = {};
      var a = this.serializeArray();
      $.each(a, function() {
      if (o[this.name] !== undefined) {
      if (!o[this.name].push) {
      o[this.name] = [o[this.name]];
      }
      o[this.name].push(this.value || ”);
      } else {
      o[this.name] = this.value || ”;
      }
      });
      return o;
      };

      and you can use simple ‘each’ (jquery or underscore) function to traverse the results

    • Stefanos

      There is not a single method that can do the job. The best combination I could find is:

      var a = [ { greet: 'hello' }, { id: 'world' } ];

      _.chain(a).map(_.pairs).flatten(true).object().value();
      // { greet: ‘hello’, id: ‘world’ }

  • http://www.thomaskuipers.nl Thomas Kuipers

    Nice article, well explained. But please format your code better. Placing as much as you can on a single line to make it seem like less code is not well suited for an article that is meant to explain something complicated.

  • Dave Stibrany

    Great primer on Underscore!

    There’s a typo and missed word in the templating section last paragraph, first sentence.

    “Keep in mind that this is an extremely demonstration of Underscore’s templaing.”

  • AllenB

    hate the syntax of underscore though I really appreciate the dude who made it (Jeremy Ashkenas).
    I use sugarjs these days (http://sugarjs.com/)

  • http://www.alfystudio.com Ahmad Alfy

    Liked it, simple and easy to understand … perhaps take us to a more complicated example?

  • Rafael

    I started to use it because underscore is one of backbone.js requirements…and I love it. Underscore.js + backbone.js + coffescript = code so much cleaner and more productivity.. i don`t live without this three resources :)

  • http://gregbabula.info Greg Babula

    Fantastic overview, I’ve been going through the docs for a while and trying to piece everything together myself and this article definitely helped me gain more understanding.

  • http://techbrij.com Brij

    It seems LINQ of .NET in javascript.
    Nice Library !!!

  • Mohamed Jama

    Awesome Lib, and by the far the prettiest source code, take a look its just PRETTY :)

  • Thomas Jane

    @Siddharth Can you write an article about Javascript Source Maps http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/

    • http://www.ssiddharth.com Siddharth
      Author

      Definitely. :)

      • Thomas Jane

        Ok! I will wait for it :)

      • Johnnyyyy

        Yesss

  • Draco

    thanks for the article, been waiting for one on underscore since I’ve been working with backbone for a while now :)

  • Cn

    Second the pretty source-code :)

  • Max Izmailov

    Um, I believe the very first example can be solved like this, without any libraries:

    var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42], scoreLimit = 90;
    var topScores = scores.filter(function(v){
    return v > scoreLimit;
    });

    Point me at my ignorance please.

    • http://www.ventanazul.com/webzine Alexis Bellido

      I think filter is only available on ECMAScript 5. The good thing about Underscore.js is that it will fall back to a native implementation if your version of ECMAScript supports a function, thus adding no overhead and keeping compatibility.

      • Pawel Dziura

        filter is replacement for select in new version of underscore.

  • Max Izmailov

    Ah, yes, IE lt 9 doesn’t have Array.filter() method.

    • http://www.ssiddharth.com Siddharth
      Author

      Indeed. Not all browsers support the methods in play here an making them all cross compatible is a nightmare.

  • Brian Frichette

    Nice overview, and I must say, you’re writing is very good.

    • DrBuckTinkler

      *your

  • http://blog.lastrose.com lastrose

    I’ve used it in node.js, and it is by far one of the most useful libraries when dealing with objects and arrays.

  • http://bartlewis.me Bart

    Great synopsis of Underscore.js. Thanks. This will undoubtedly come in handy, on some future projects.

  • http://playcu.bz rudifa

    Hello Siddharth

    Nice tutorial, many thanks from a js newcomer!

    I have taken the liberty to wrap your code examples in a read-to-display html page, available at http://pastebin.com/cMHi82We .

    Hope it helps to anyone interested.

    @rudifa

    • http://playcu.bz rudifa

      oops, I meant “ready-to-display html page”, please fix my typo

      @rudifa

  • http://www.interactivered.com interactive red

    Great Lib, and great article thanks

  • Paul

    What’s the difference with sugar.js?
    thanks

  • Mickey Mouse

    Decent article, you you screwed up the bend by poorly explaining the Functions and Utility (Template) parts.

    • http://www.ssiddharth.com Siddharth
      Author

      Thanks for the critique. :)

      I’ll looking into exploring those topics in a future article.

  • http://palpaldal.com Nuruzzaman Sheikh

    Wow I’m loving it (_). Thanks a lot Siddharth you are awesome. And it’s a true useful library I’m going to give it a try soon.

  • http://www.istudio.com.mx Alfredo Ramirez

    So much to learn…to little time to do it. Thanks!!

  • aveic

    I’ve made up a cheat sheet for underscore.js. You can grab it here http://aveic.ru/underscorejs/cheatsheet.pdf

  • Henry

    How does underscore.js compare to handlebars.js?

    Seems like handlebars is killing every other templating engine: http://jsperf.com/dom-vs-innerhtml-based-templating/365

    Does handlebar have functions for array & object like underscore?

  • Rafael

    Thanks for the excelente explanation about unserscore… You did it very well !!

  • http://twitter.com/webdwall webdeveloperswall

    one of the top pages in google search result when i type in ‘learn underscroe.js’. great tutorial! thank you. i specially liked ‘nerdgasm’… ROFL :)

  • mbokil

    I think you could clarify greet(“Jess”) with console.log( greet(“Jess”) );

  • http://www.facebook.com/Kaminsky.Pavel Pavel ‘PK’ Kaminsky

    Excellent lib for the cost of 41kb.

    One point worth mentioning thought , if you’re *already using jQuery* in your project
    chances are you can achieve many of this effects for free.
    But, if you’re into building a code that will last, _ is great.

  • greenlinux

    If JavaScript is slowly moving out of the browser, what do you recommend to learn, in order to replace JavaScript?

  • Parag

    How do we achieve localization in underscore?

  • PerlUser

    Wow, if that gave you a nerdgasm then reading well written Perl code would probably send you in an infinite multi-nerdgasm loop….

    @scores = (84, 99, 91, 65, 87, 55, 72, 68, 95, 42);

    $scoreLimit = 90;

    @topScorers = grep { $_ > $scoreLimit } @scores;

    say “@topScorers”;

    Now that´s what I consider concise and clear…