Underscore.js is a JavaScript library that provides a comprehensive set of utility functions for common programming tasks. It offers support for functional programming principles, making it easier to work with arrays, objects, and other data types. This guide will provide an overview of Underscore.js, its key features, and some practical examples of its use.


Introduction to Underscore.js

Underscore.js is a utility-belt library for JavaScript that provides numerous helper functions for tasks such as data manipulation, functional programming, templating, and more. It allows developers to write cleaner and more concise code by abstracting common operations into simple function calls.

To use Underscore.js, you need to include it in your project. You can either download the library from the official website or include it via a CDN. Here’s how you can include it using a CDN:

 
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.4/underscore-min.js"></script>

Once included, all Underscore functions are available through the _ object.


Key Features and Examples
Collections

Underscore.js provides various functions for dealing with collections (arrays and objects).


_.each

The _.each function iterates over a list of elements, yielding each in turn to an iteratee function.

 
let numbers = [1, 2, 3, 4, 5];
_.each(numbers, function(num) {
  console.log(num);
});
// Output: 1, 2, 3, 4, 5


_.map

The _.map function produces a new array of values by mapping each value in a list through a transformation function (iteratee).

 
let numbers = [1, 2, 3, 4, 5];
let squares = _.map(numbers, function(num) {
  return num * num;
});
console.log(squares);
// Output: [1, 4, 9, 16, 25]


_.filter

The _.filter function looks through each value in a list and returns an array of all the values that pass a truth test (predicate).

 
let numbers = [1, 2, 3, 4, 5];
let evenNumbers = _.filter(numbers, function(num) {
  return num % 2 === 0;
});
console.log(evenNumbers);
// Output: [2, 4]


Arrays

Underscore.js provides several functions for manipulating arrays.


_.first and _.last

The _.first function returns the first element of an array. If a number is provided, it returns the first n elements.

 

let numbers = [1, 2, 3, 4, 5];
console.log(_.first(numbers));
// Output: 1
console.log(_.first(numbers, 3));
// Output: [1, 2, 3]
 
 

The _.last function works similarly but returns the last element(s).

let numbers = [1, 2, 3, 4, 5];
console.log(_.last(numbers));
// Output: 5
console.log(_.last(numbers, 3));
// Output: [3, 4, 5]


_.uniq

The _.uniq function returns a duplicate-free version of an array.

 
let numbers = [1, 2, 1, 4, 1, 3];
let uniqueNumbers = _.uniq(numbers);
console.log(uniqueNumbers);
// Output: [1, 2, 4, 3]


_.flatten

The _.flatten function flattens a nested array (the nesting can be to any depth).

 

let nestedArray = [1, [2], [3, [[4]]]];
let flatArray = _.flatten(nestedArray);
console.log(flatArray);
// Output: [1, 2, 3, 4]
 


Objects

Underscore.js offers functions for manipulating objects.


_.keys and _.values

The _.keys function retrieves all the names of the object's properties.

 
let obj = { one: 1, two: 2, three: 3 };
let keys = _.keys(obj);


console.log(keys);
 
// Output: ['one', 'two', 'three']

The _.values function retrieves all the values of the object's properties.

 

let obj = { one: 1, two: 2, three: 3 };
let values = _.values(obj);
console.log(values);
// Output: [1, 2, 3]
 


_.extend

The _.extend function copies all properties from source objects to a destination object.

 
let obj1 = { a: 1 };
let obj2 = { b: 2 };
let extendedObj = _.extend(obj1, obj2);
console.log(extendedObj);
// Output: { a: 1, b: 2 }


Utility Functions

Underscore.js also includes a variety of utility functions.


_.noConflict

The _.noConflict function returns the _ variable to its previous owner and returns a reference to the Underscore object.

 
let underscore = _.noConflict();
// Now `underscore` can be used in place of `_`


_.identity

The _.identity function returns the same value that is used as the argument. This function is often used as a default iteratee.

let numbers = [1, 2, 3, 4, 5];
let identities = _.map(numbers, _.identity);
console.log(identities);
// Output: [1, 2, 3, 4, 5]


_.times

The _.times function invokes a given function a specified number of times.

 
_.times(3, function(n) {
  console.log(n);
});
// Output: 0, 1, 2


Practical Examples
Example 1: Grouping Objects by Property

Suppose you have an array of objects representing people and you want to group them by age.

 

let people = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 25 }
];

let groupedByAge = _.groupBy(people, 'age');
console.log(groupedByAge);
// Output:
// {
//   25: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
//   30: [{ name: 'Bob', age: 30 }]
// }
 

Example 2: Finding the Maximum Value in an Array

Using Underscore.js, you can find the maximum value in an array with the _.max function.

let numbers = [10, 5, 100, 2, 1000];
let maxNumber = _.max(numbers);
console.log(maxNumber);
// Output: 1000
 

Example 3: Deep Cloning an Object

To deep clone an object, you can use a combination of _.clone and _.extend.

 

let obj = { a: 1, b: { c: 2 } };
let deepClone = _.clone(obj);
deepClone.b.c = 3;
console.log(obj.b.c); // Output: 2 (original object remains unchanged)
console.log(deepClone.b.c); // Output: 3
 

 



Practice Excercise Practice now