Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Learning UnderscoreJS
Learning UnderscoreJS

Learning UnderscoreJS: Explore the Underscore.js library by example using a test-driven development approach

eBook
$9.99 $39.99
Paperback
$48.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Learning UnderscoreJS

Chapter 1. Getting Started with Underscore.js

This chapter introduces you to Underscore and explains the main problems addressed by this library together with a quick introduction to functional programming. The chapter describes some of the concepts and patterns that are used by Underscore or are helpful when using Underscore. The final part is a walkthrough to set up the development environment used throughout the book.

The topics covered in this chapter are as follows:

  • Why Underscore
  • Getting started with Underscore by example
  • Key Underscore functions
  • Functional programming fundamentals
  • Useful patterns and practices for JavaScript applications targeting ECMAScript 5
  • Setting up a development workflow to explore Underscore
  • Testing JavaScript code with Jasmine

The chapter assumes that you know JavaScript programming fundamentals and how to create basic web pages using HTML, CSS, and jQuery.

The source code for all the examples from this chapter is also hosted online on GitHub at https://github.com/popalexandruvasile/underscorejs-examples/tree/master/getting-started.

Why Underscore

In the last couple of years, the JavaScript programming language has extended its reach dramatically. While initially it was a browser-based scripting language, it is now used in server-side applications via platforms such as Node.js or in mobile and desktop applications via frameworks such as PhoneGap and Node-Webkit. Database engines such as MongoDB and PostgreSQL also use JavaScript, and this makes it possible to write an application using the same programming language throughout all its layers and components. Another significant change that raised the importance of JavaScript was the emergence of libraries and frameworks that targeted the browser as an application platform. Libraries such as jQuery enabled cross-browser HTML element manipulation, among other features, and frameworks such as Backbone.js facilitated building single page applications.

Note

A single page application (also known as SPA) has the user interface rendering and navigation happening in the browser rather than on the server.

The library presented in this book is called Underscore and provides an extensive set of functions that simplify and enhance handling of JavaScript objects, arrays, and functions. It accomplishes this by providing missing functional programming features to JavaScript. By using Underscore JavaScript gains a better level of usability that makes coding easier and more expressive on a similar level to other general purpose programming languages.

Version 1.0 of Underscore was launched in 2010 around the time when single page applications started to gain more ground. Underscore is used in Backbone.js as both have the same author, and after its launch it has become one of the most popular JavaScript libraries. At the time of writing this book, Underscore has reached version 1.8.3, which will be the version used throughout all examples.

Underscore is representative of a good JavaScript utility library as it provides solutions for a specific problem domain rather than being a catchall utility. It also has very good online documentation (including annotated source code) that is available at http://underscorejs.org/, which is another distinctive attribute of a good software library. This book will explore Underscore by presenting a series of more involved examples than the ones provided with its library documentation.

To understand why Underscore is so popular, we need to discuss the ECMAScript 5 (ES5) specification and what it meant for JavaScript as a programming language. Technically, JavaScript is a specific implementation of an open language specification called ECMAScript. The current version of this specification was finalized at the end of 2009 and is known as ECMAScript 5 (or ECMAScript 5.1 to be very specific). This version added functionality for the built-in JavaScript objects, Array and Object, included new functional features, and improved the meta-programming story among other changes. Soon after its release, it started to be adopted by all major browsers, including Internet Explorer from version 9. There was still a large number of users relying on browsers such as Internet Explorer 6, 7, and 8 that were unlikely to upgrade too quickly to Internet Explorer 9 compared to users of browsers such as Mozilla Firefox and Google Chrome that had faster release and upgrade cycles. As Underscore provided support for some of the functionality introduced by ECMAScript 5, this made it a useful library for web applications targeting older browsers such as Internet Explorer 8, and for developers that wanted to write code that was based on ES5 without worrying about browser support. Although ES5 support is important, this is just a small feature of Underscore compared to the rest of its features.

All of this book's examples assume that they are executed against a JavaScript version that is ES5 compliant. All the examples can be executed on Windows, Mac OS X, and Linux, and we will mainly target Google Chrome and Mozilla Firefox that are the most popular cross platform browsers (although you should not have issues running the examples in other browsers).

Note

Technically, Underscore is not directly compatible with ES5 starting from version 1.7.0, and we will discuss more about standards compliance in Chapter 6, Related Underscore.js Libraries and ECMAScript Standards.

ES 5 support for older browsers should be provided through a library targeting this feature exclusively such as es5-shim. This library is available at https://github.com/es-shims/es5-shim, where you can find more details about its features.

Getting started with Underscore by example

The best way to introduce Underscore is with examples. We will target the same problem and solve it first using plain JavaScript that is ES5 compliant followed by a couple of Underscore-based solutions.

The ECMAScript 5 starter example

The examples presented in this chapter are hosted in web pages, and they can be executed by opening the index.html example file in your preferred web browser.

We start with a dataset that contains various bicycles and each one has a specific type. We want to process the dataset and get a count of bicycles for each bicycle type. The dataset is represented by an array of bicycle objects created using the object literal notation:

var bicycles = [{
      name: "A fast bike",
      type: "Road Bike"
    }, {
      name: "An even faster bike",
      type: "Road Bike"
    }, {
      name: "A springy bike",
      type: "Mountain Bike"
    }, {
      name: "A springier bike",
      type: "Mountain Bike"
    }, {
      name: "An all-terain bike",
      type: "Mountain Bike"
    }, {
      name: "A classy bike",
      type: "Urban Bike"
    }, {
      name: "A modern bike",
      type: "Urban Bike"
    }, {
      name: "A blue bike",
      type: "Children Bike"
    }, {
      name: "A pink bike",
      type: "Children Bike"
    }, {
      name: "A noisy bike",
      type: "Children Bike"
    }, {
      name: "A clown bike",
      type: "Children Bike"
    }];

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Next, we will define a function that processes the dataset and creates an array of objects that contains the count of bicycles for a specific bicycle type:

var getBicyclesCountPerType = function() {
  var bicyclesCountPerType = [];
  bicycles.forEach(function(bicycle) {
    var isExistingType = false;
    bicyclesCountPerType.forEach(function(typeCount) {
      if (typeCount.type === bicycle.type) {
        typeCount.count += 1;
        isExistingType = true;
      }
    });
    if (!isExistingType) {
      bicyclesCountPerType.push({
        type: bicycle.type,
        count: 1
      });
    }
  });
  return bicyclesCountPerType;
};

The first highlighted function forEach is ES5 specific and enumerates the values of an array while executing a function for each element in the array. The forEach function is defined against Array.prototype, so it will be available to any Array instance.

The final code snippet for the first example relies on jQuery to append the results for each bicycle type as HTML content:

$(document).ready(function() {
  var outputContent = "There are " + bicycles.length + " bicycles:"
  var results = getBicyclesCountPerType();
  results.forEach(function(typeCount) {
    outputContent += "<br />";
    outputContent += " - " + typeCount.count + " of type: " + typeCount.type;
  });

  $("#output").html(outputContent);
});

Notice how we use forEach again to enumerate the final results. You can explore the example in the starter-example-with-ECMAScript5 folder from the source code for this chapter. In order to run this example, you need to open the index.html file in your preferred web browser. The example can also be executed directly at http://bit.ly/1WLzHuS.

You can view the example output in this screenshot:

The ECMAScript 5 starter example

The Underscore find starter example

In the previous example, we used two-nested forEach calls, and this approach seems inefficient under closer scrutiny. You cannot break a forEach loop, which means that you cannot stop after you processed the specific elements that were targeted. The second nested forEach call only needs to process a target element from the list rather than iterating the full list every time. Fortunately, Underscore has a function called find that iterates an array and stops when an element matching a specific criteria is found.

To use Underscore, we need to add a reference to a hosted version of the library in the head element of the example web page:

<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>

In the first example, we changed the function getBicyclesCountPerType() to use the Underscore find function:

var getBicyclesCountPerType = function() {
  var bicyclesCountPerType = [];
  bicycles.forEach(function(bicycle) {
    var currentTypeCount = _.find(bicyclesCountPerType, function(typeCount){
      return typeCount.type === bicycle.type;
    });
    if (currentTypeCount) {
      currentTypeCount.count += 1;
    }
    else
    {
      bicyclesCountPerType.push({
        type: bicycle.type,
        count: 1
      });
    }
  });
  return bicyclesCountPerType;
};

The code is terser and more efficient thanks to the find function, while the rest of the example remains unchanged. You can explore the full example in the starter-example-with-underscore.find folder from the source code for this chapter or by running it directly at http://bit.ly/1U7dVO4.

All Underscore functions are usually accessed through the Underscore global object named _. This name can be changed if it conflicts with other global variable names, and we will explore how to do this in Chapter 4, Programming Paradigms with Underscore.js. We will stick with the default Underscore global object name for most of the examples.

The full signature of the find function is _.find(list, predicate, [context]). This function accepts an array or an object as its first parameter list followed by a function parameter predicate that will be executed against each element of the array or against each property value of the object passed as the first parameter. The second parameter function predicate accepts an array element or an object property value and should return a Boolean value. If the return value is true, the _.find() function will stop iterating and will return the array element or the property value from the current position. The last optional parameter context is rarely used in this book and will be covered later on when we discuss scopes and the value of the this object. The find function signature was briefly explored here as it is used extensively in Underscore and subsequently in the rest of the examples.

Note

In ES6, there is also a find function defined against Array.prototype that can be used as an alternative. We will discuss this function and other similar ECMAScript 6 functions in Chapter 6, Related Underscore.js Libraries and ECMAScript Standards.

The Underscore countBy starter example

The previous example introduced Underscore as an incremental improvement compared to the example before that. Among Underscore's 100+ functions, there is one that can replace the getBicyclesCountPerType() function completely and significantly reduce the number of lines of code. This function is countBy and its signature is _.countBy(list, iteratee, [context]). While its signature is similar with the one for the find function, the second function parameter iteratee is expected to return a string value representing a key for the iterated item. The key is used to group different elements of an array or different object property values depending on the list parameter type.

The countBy function returns an object with properties that have names taken from the keys supplied by the iteratee function. The value of such a property is the count of items from the list parameter that share the current property name as key.

The getBicyclesCountPerType() function invocation can be completely replaced with the _.countBy() function invocation:

var result = _.countBy(bicycles, function(bicycle){
    return bicycle.type;
});

The result object value has the following JSON representation:

{
    "Road Bike": 2,
    "Mountain Bike": 3,
    "Urban Bike": 2,
    "Children Bike": 4
}

The code tasked with displaying the example output needs to be changed accordingly. Instead of manipulating the array returned by the getBicyclesCountPerType() function it should manipulate the result object properties. We will use another Underscore function _.pairs(), which converts object properties to an array of elements where each element is a property name and value pair. Such a pair is a two-dimensional array itself, and you can see how it is declared and referenced in the highlighted sections from the following example:

$(document).ready(function() {
  var outputContent = "There are " + bicycles.length + " bicycles:"
  var result = _.countBy(bicycles, function(bicycle) {
    return bicycle.type;
  });
  _.pairs(result).forEach(function(typeCountPair) {
    var key = typeCountPair[0];
    var value = typeCountPair[1];
    outputContent += "<br />";
    outputContent += " - " + value + " of type: " + key;
  });
  $("#output").html(outputContent);
});

We have now dramatically reduced the size of the initial example by using Underscore functions while maintaining the same functionality. You can explore the full example in the starter-example-with-underscore.countBy folder from the source code for this chapter or by running it directly at http://bit.ly/1JdNwc6.

We started with one example that uses ES5 functions, followed by one that uses an Underscore function that is also an ES6 function. The final example uses another Underscore specific function that provides a higher level of data manipulation compared to built in JavaScript functions. You should find a lot more Underscore examples of this kind throughout the book.

Key Underscore functions

Out of the many Underscore functions, there are a couple that deserve special attention as they provide a good introduction to a range of similar functions. These functions are essential when processing data, they have an equivalent in the ES5 specification, and they are: each, map, and reduce.

Underscore each

In the first example, we used the ES5 function Array.prototype.forEach to iterate the initial dataset. Underscore also provides its own version called _.each(). The main difference from the Array.prototype.forEach function is that _.each() can be used against object properties if an object rather than array is provided as its first argument. The full function signature is _.each(list, iteratee, [context]) and it will call the second function parameter iteratee against each item of the iterated list object or array passed as its first argument. To use this function in the second example starter-example-with-underscore.find from this chapter, we just need to replace this line from the getBicyclesCountPerType() function:

bicycles.forEach(function(bicycle) {

With line:

_.each(bicycles, function(bicycle) {

Underscore each has a forEach alias, so it can be called in a similar way with its ES5 equivalent:

_.forEach(bicycles, function(bicycle) {

Another difference from the ES5 equivalent is that Underscore each returns the first parameter as opposed to undefined allowing further function call chaining. Underscore also has first class support for function chaining that will be detailed in Chapter 4, Programming Paradigms with Underscore.js.

We will explore calling each over object properties together with other Underscore functions mentioned in this chapter in Chapter 2, Using Underscore.js with Collections.

Underscore map and reduce

The next Underscore functions of special interest are map and reduce. The Underscore map function signature is similar to the each function signature: _.map(list, iteratee, [context]). It transforms a list array or object parameter into a new array that contains modified elements or property values of the list parameter. The transformation is made by:

  • Iterating the elements or properties of the list parameter using the second parameter function iterate, and calling this function for each item;
  • Collecting the values of the iteratee call into the array returned by the _.map() function.

Underscore reduce is a function that converts an array or object properties into a single value. The function signature is _.reduce(list, iteratee, [memo], [context]) and the optional memo parameter is used as the seed for the returned value. If memo is not specified, then the first element or object property value of the list parameter will be used as the seed value instead. The iteratee function signature is iteratee(memo, element, index, list) when list is an array like object. The value returned by iteratee is either supplied as the memo parameter for the next iteration or is returned as the final reduce value if there are no more iterations left.

The next example will showcase these two functions by iterating over an array of people that have received an important award at some point in their lives—the Nobel prize for literature. The example calculates the age when the award was received using _.map() and the average value of the age when the award was received using _.reduce().

This is the initial dataset:

var people = [{
    name: "Herta Muller",
    birthYear: 1953,
    awardYear: 2009
  }, {
    name: "Mario Vargas Llosa",
    birthYear: 1936,
    awardYear: 2010
  }, {
    name: "Tomas Transtromer",
    birthYear: 1931,
    awardYear: 2011
  }, {
    name: "Mo Yan",
    birthYear: 1955,
    awardYear: 2012
  }, {
    name: "Alice Munro",
    birthYear: 1931,
    awardYear: 2013
  }, {
    name: "Patrick Modiano",
    birthYear: 1945,
    awardYear: 2014
  }];

First, we calculate the age when the award was received for each person by using _.map():

var peopleWithAwardAge = _.map(people, function(person){
  return {
    name: person.name,
    awardAge: person.awardYear - person.birthYear
  }
});

Next, we calculate the average age of the award by using _.reduce() and passing 0 as the memo seed value:

var totalAge = _.reduce(peopleWithAwardAge, function(memo, person) {
  return memo + person.awardAge;
}, 0);
var averageAwardAge = totalAge / peopleWithAwardAge.length;

You can explore the complete example in the underscore.map.reduce folder from the source code for this chapter or by running it directly at http://bit.ly/1MMSOlc.

Functional programming fundamentals

In the previous example, we transformed an existing dataset into a new structure rather than modifying it (mutating it) by using the two powerful Underscore functions _.map() and _.reduce(). This is a typical example of a functional programming style in action: we use functions also known as higher-order functions that accept other functions as parameters, and we don't alter (mutate) the state of variables such as people and peopleWithAwardAge once they are created—the data that we work with is immutable.

Functional programming (FP) is a declarative programming paradigm in which functions are first class citizens that are treated as values (data), and the application code avoids mutating existing states. In an FP language, you also find that:

  • Functions called higher-order functions can be used to compose other functions by accepting functions as arguments or by returning functions.
  • Functions that don't have side effects are called pure functions, and if they are called repeatedly with the same parameters, they return the same result. They don't have any dependency on data outside their function scope.

There are many aspects of FP such as extensive use of recursion, employing lazy evaluation, and built-in support for pattern matching that are implemented to various degrees in FP languages. Languages such as Erlang, Haskell, Clojure, and F# (to name just a few) are considered functional languages, while languages such as C#, JavaScript, and Java 8 have limited support for a functional programming style. Languages such as Scala are classified as object-functional—a bridge between FP and OOP (object-oriented programming) paradigms.

JavaScript can be used in a functional programming style through its built in support for functions as first class citizens, higher-order functions, by simulating immutability and using its limited recursion capabilities. We will explore JavaScript functional aspects in Chapter 4, Programming Paradigms with Underscore.js and where needed in other chapters.

Useful patterns and practices for JavaScript applications targeting ECMAScript 5

The examples we have used so far had an introductory role and they are not representative of a production ready application. One of the goals of this book is to present examples that are closer to real life usage and the rest of the examples will follow this goal. As a first step, we need to introduce some JavaScript patterns and practices that will be useful in organizing and driving the rest of the examples in this book. They are essential when writing ES5 code, but you don't need them when writing ES6 code using classes and modules (more details about ES6 and how it improves code quality will be discussed in Chapter 6, Related Underscore.js Libraries and ECMAScript Standards).

One of the difficult problems to solve when writing JavaScript code is to avoid the pollution of the global scope. Any variable declared outside of a function body will automatically be visible in the global scope. You can easily imagine a scenario where your variable names clash with the variables defined in other JavaScript files or libraries. Also, JavaScript automatically moves all variable declarations to the top of the current scope. This behavior is called hoisting and can lead to scenarios where you use a variable before it is declared, which is confusing and can cause unintended errors.

To avoid these problems, a typical workaround is to use a function body to declare your variables. Variables declared in this way belong to the local scope of the enclosing function, and they are invisible to the global scope. This workaround is based on two patterns used frequently in JavaScript applications: the immediately invoked function expression (IIFE)—pronounced "iffy"—and the revealing module pattern.

The immediately-invoked function expression

If we append the line, console.log(people.length);, at the end of the script section from the previous example found in the underscore.map.reduce folder, we will see the length of the array written in the console as 6. If we convert the example to use an immediately invoked function expression, the script section will look like the following code (with most of the code removed for brevity):

(function(){
  var people = […];
  $(document).ready(function() {…});
}());
console.log(people.length);

You can view the preceding example either online at http://bit.ly/1WNL31t or in the underscore.map.reduce-iife folder from the source code for this chapter.

I have highlighted the changes required to convert the code to use the immediately invoked function expression. Sometimes, a leading semicolon is used to prevent issues caused by the automatic semicolon insertions in JavaScript when your scripts get concatenated with other scripts. The enclosing parentheses around the highlighted self-executing anonymous function and before the last semicolon are the signature for these types of expression.

The example will still work as before, but the console output will have this message: Uncaught ReferenceError: people is not defined. Using this pattern, we made the people variable inaccessible for the global scope, while leaving it available for the IIFE function scope. The Underscore library is using an IIFE that contains all its source code and we will follow suit by ensuring the rest of the examples will use this pattern whenever applicable.

Next, we will explore a JavaScript pattern that also prevents exposing data to the global scope and is useful for safely sharing application code between different components in JavaScript.

The revealing module pattern

The revealing module pattern solves the problem of hiding implementation details for JavaScript objects that expose property-like objects or functions to the global scope. The following example is a plain JavaScript one—no external library references are required:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Getting started - Revealing module pattern</title>
</head>
<body>
  <h1>See browser console for example output.</h1>
  <script>
    var revealingModule = (function() {
      var innerObject = 5;
      var innerFunction = function(value) {
        return innerObject + value;
      };
      return {
        outerObject1: innerFunction(1),
        outerObject2: innerFunction(2),
        outerFunction: innerFunction
      };
    }());
    console.log("outerObject1:" + revealingModule.outerObject1);
    console.log("outerObject2:" + revealingModule.outerObject2);
    console.log("innerObject:" + revealingModule.innerObject);
    console.log("outerFunction(3):" + revealingModule.outerFunction(3));
    console.log("innerFunction(3):" + revealingModule.innerFunction(3));
  </script>
</body>
</html>

You can view the example either online at http://bit.ly/1hUg2J5 or in the revealing-module-pattern folder from the source code for this chapter.

The first highlighted code represents the object created through the revealing module pattern, and you will notice that it relies on an IIFE to define itself. Using this pattern, all of the variables declared inside the IIFE are inaccessible to the outside scope, and the only visible properties are the ones returned in the object created in the last highlighted code snippet. The console output for this example is shown as follows:

outerObject1:6
outerObject2:7
innerObject:undefined
outerFunction(3):8
Uncaught TypeError: undefined is not a function

Any reference to the variables defined within the IIFE will be unsuccessful as demonstrated by the exception raised when the innerFunction was called within the global scope. You will see this pattern in action throughout this book, as we will use it in many examples. The Underscore library is using a version of this pattern and exposes all its global accessible functions though its _ object. The annotated Underscore source code available at http://underscorejs.org/docs/underscore.html is great for exploring how the library works behind the covers and is the recommended companion for this book.

Note

You can find more information about the revealing module pattern and other JavaScript design patterns in the online resource Learning JavaScript Design Patterns, Addy Osmani, O'Reilly Media, available at http://addyosmani.com/resources/essentialjsdesignpatterns/book/.

Next, we will convert the underscore.map.reduce-iife example code to use the revealing module pattern and define a global accessible object called awardAgeCalculator. This object exposes all relevant functions that need to be accessible outside the IIFE scope as shown in the next code snippet:

var awardAgeCalculator = (function() {
  var getPeople = function() {
    return [{
      name: "Herta Muller",
      birthYear: 1953,
      awardYear: 2009
    }, {
       ...
    }, {
      name: "Patrick Modiano",
      birthYear: 1945,
      awardYear: 2014
    }];
  };

  var innerGetPeopleWithAwardAge = function() {
    return _.map(getPeople(), function(person) {
      return {
        name: person.name,
        awardAge: person.awardYear - person.birthYear
      };
    });
  };

  return {
    getPeopleWithAwardAge: innerGetPeopleWithAwardAge,
    getAverageAwardAge: function() {
      var peopleWithAwardAge = innerGetPeopleWithAwardAge();
      var totalAwardAge = _.reduce(peopleWithAwardAge, function(memo, person) {
        return memo + person.awardAge;
      }, 0);
      return totalAwardAge / peopleWithAwardAge.length;
    }
  };
}());

You can find the example in the underscore.map.reduce-revealing-module folder from the source code for this chapter or you can execute it online at http://bit.ly/1h7eg6x.

I have highlighted the two functions that are defined in the local IIFE scope and cannot be accessed directly unless they are referenced as properties in the object returned by the awardAgeCalculator IIFE. Notice the functional style used in the example; apart from the awardAgeCalculator object, we use only functions throughout and don't have any variable inside awardAgeCalculator that preserves its value between any two function calls. We will continue to use this approach to define the core functionality of an example and here is how awardAgeCalculator is used to generate the example output as part of the same example:

$(document).ready(function() {
  var outputContent = "<br />Award age for people:";
  _.each(awardAgeCalculator.getPeopleWithAwardAge(), function(person) {
    outputContent += "<br />";
    outputContent += " - " + person.name + " was " + person.awardAge + " years old";
  });
  var averageAwardAge = Math.floor(awardAgeCalculator.getAverageAwardAge());
  outputContent += "<br /><br />" + "Average award age is " + averageAwardAge + " years old.";
  $("#output").html(outputContent);
});

I have highlighted the usages of the awardAgeCalculator functions, and we obtained a better separation of the code and simplified the example output section.

Note

We can encounter an issue if we reference other JavaScript files that might also declare an awardAgeCalculator variable. Choosing the name of your global accessible objects is very important because of this issue, and it is a very difficult problem to solve without a dependency management utility. We will discuss how we can avoid this issue and other ways to organize JavaScript code in Chapter 6, Related Underscore.js Libraries and ECMAScript Standards.

The JavaScript strict mode

ES5 has introduced a new way to use a stricter variant of JavaScript called strict mode. This variant changes the behavior of the JavaScript runtime, and the following are some changes that occur in strict mode:

  • Some silent errors are thrown instead of being ignored, such as assignment to a nonwritable property.
  • All global variables need to be explicitly declared. When you mistype a global variable name, an exception is thrown.
  • All of the property names of an object need to be unique, and all of the parameter names for a function also need to be unique.

By including the line "use strict"; in your scripts, you can adhere to this JavaScript variant when using a modern ES5-compliant browser. If the script is loaded in an older browser, the statement is ignored and the JavaScript is parsed in non-strict mode. Strict mode can only be safely declared at the top of a function body. If it is declared in the global scope, it can cause issues when a strict mode script is concatenated with other non-strict scripts.

Using strict mode leads to safer, cleaner code with fewer errors. All examples throughout the rest of the book will use the patterns and practices discussed in this section.

Setting up a development workflow for exploring Underscore

The examples we used so far can be executed directly and their external JavaScript dependencies such as jQuery and Underscore are referenced using publicly hosted files. This is great for quick examples and rapid prototyping but not a recommended practice when building any non-trivial application. We will next set up a development workflow that is popular with JavaScript developers. This workflow will help us build examples efficiently and is close to what a real-life JavaScript application will use.

Modern JavaScript development with Node.js

The process of building modern JavaScript applications is greatly simplified by leveraging the rich ecosystem powered by Node.js.

Node.js is a software runtime for building server-side applications using JavaScript. Internally, it uses the V8 JavaScript engine that powers the Google Chrome web browser to compile JavaScript code to native code before executing it. It is based on an asynchronous event-driven programming model with non-blocking I/O operations using a single thread of execution. This makes it a great fit for real-time applications and high-throughput web applications. Node.js benefits from all the optimizations and performance improvements that Google Chrome has introduced since its first version and it runs on all major operating systems: Linux, Mac OS X, and Windows.

The Node.js installation comes with a built-in package manager called npm that contains a very large number of packages. There is an online npm packages repository available at https://www.npmjs.org/ that is used for installing or updating Node.js application dependencies.

For setting up the Node.js environment, we will target the Windows operating system first with Mac OS X and Linux covered next.

Windows

You need to install Node.js, which comes in 32-bit and 64-bit versions by going to https://nodejs.org/download/, and select one of the packages that matches your OS. You can use https://nodejs.org/dist/v0.12.7/node-v0.12.7-x86.msi for the 32-bit version or https://nodejs.org/dist/v0.12.7/x64/node-v0.12.7-x64.msi for the 64-bit version (the available versions may be different at the time you are reading this book). We have used the 64-bit version with the examples from this book. As an alternative installation method, you can use the Chocolatey package manager for Windows and install it using the instructions provided at https://chocolatey.org or by executing the following line in a Command Prompt with administrator privileges (opened using the Run as administrator option):

@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin

With Chocolatey now available, we can use it to install Node.js by executing the following command:

choco install -y node.js

Mac OS X

On Mac OS X, we will use the Homebrew package manager for OS X that can be installed by following the instructions at http://brew.sh or by executing the following command line in the terminal:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

With Homebrew now available, we can use it to install Node.js by executing the following command:

brew install node

Linux

Ubuntu 14.04 was the target Linux distribution used to test the examples from this book, but you should be able to use any Linux distribution you prefer. Ubuntu comes with its built-in package manager, and we will use it to execute the commands requires to register the Node.js repository used in this book (more details at http://bit.ly/1hcVaMm):

sudo apt-get install -y curl
curl -sL https://deb.nodesource.com/setup_0.12 | sudo bash -

With the Node.js repository now configured in Ubuntu, we can install Node.js with the following command:

sudo apt-get install -y nodejs

Verifying Node.js installation

To verify that Node.js has installed correctly, we need to open the OS-specific Command Prompt and execute the following command:

node -v

If you see v0.12.07 on the screen, it means that Node.js has installed correctly, and we can execute all the examples from this book without any other OS-level changes.

Note

We will explore more about Node.js and npm packages in Chapter 5, Using Underscore.js in the Browser, on the Server, and with the Database.

Managing JavaScript dependencies with Bower

With Node.js installed, we have access to its large repository of development tools and libraries provided through npm. We will use npm to install Bower, which is a package manager optimized for web sites and web applications. Bower is very similar to npm with the main difference being that Bower packages maintain a flat dependency tree as opposed to npm packages that maintain a deep nested dependency tree. For example, if two Bower packages have a dependency on Underscore, only one version of the Underscore package will be installed. If two npm packages have a dependency on Underscore, each package will install its Underscore package separately (although npm 3 will use flat dependencies by default similar to Bower).

Note

Bower has a dependency on the Git source control system, which can be installed from this location http://git-scm.com/downloads.

To install Bower, you need to open a Command Prompt and execute this npm command:

npm install -g bower

Notice the -g npm command-line switch, which installs the package in the machine specific npm packages folder. By default, npm packages are installed relative to the current directory unless this command switch is specified. From now on, Bower will be available to all our examples regardless of the folder in which they reside.

Next, we will use the previous example found in the underscore.map.reduce-revealing-module folder from the source code for this chapter and transform it into a new example that leverages Bower for package management.

By running the following command in the example folder, we will create a bower.json file that holds metadata about the current project and its dependencies:

bower init

When running this command, there are a series of Command Prompt options that can be accepted with their default values. The values will be updated in the bower.json file. Next, we will install the Bower packages that match the required JavaScript library dependencies for jQuery and Underscore:

bower install jquery#2.1.4 --save
bower install underscore#1.8.3 --save

Notice the package name jquery followed by the version target #2.1.4 that ensures that we are using only a specific version of a Bower package rather than the latest version available when we omit the version target. The last command-line switch --save will persist the package information in the bower.json file allowing an easy restore for the Bower packages if they get deleted locally or they are not committed with the source code for the current project.

We now have the two JavaScript libraries installed in the current folder within a bower_components subfolder, which is the default Bower location for storing packages.

We can now change the JavaScript references in the index.html file to point to the two local Bower packages rather than the online hosted files:

<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/underscore/underscore.js"></script>

I have also moved the inline JavaScript code into two separate files called awardAgeCalculator.js and index.js that separate the core functionality in the former from the output specific code in the latter. You can find the example in the underscore.map.reduce-with-local-dependencies folder from the source code for this chapter.

By leveraging Bower, we can quickly reference any JavaScript library that is needed while making it very easy to share the current project with other developers or even publish it to the Bower package repository.

Choosing a JavaScript editor

We are approaching the end of the first chapter, and so far, we have not mentioned any tool for editing the code used in the example. Actually, we don't really have to as modern JavaScript development relies on a command-line-based tool chain usually based on Node.js. The workflow we established for exploring the examples from this book does not require a specific visual editor to be installed. You could just use the default operating system text editor and stop at that. However, it is worth mentioning the existing rich ecosystem of JavaScript visual editors and IDEs that is available if you want to benefit from additional functionality.

There are both commercial and free to use tools available, and they are separated into two categories: tools that have a main focus on Node.js and JavaScript-based development, and tools for general development that support Node.js and JavaScript through a plugin system. Note that we mentioned both Node.js and JavaScript as requirements for any editor or IDE as Node.js will be used extensively later on in this book.

Out of the Node.js and JavaScript-specific commercial tools, it is worth mentioning WebStorm IDE (more details at https://www.jetbrains.com/webstorm/) and Cloud9 online IDE that allows browser-based JavaScript development among other languages (more details at https://c9.io/). There is even a free Microsoft Visual Studio plugin called Node.js Tools for Visual Studio development (more details at http://nodejstools.codeplex.com/).

Out of the editors supporting JavaScript via their plugin system, I will mention the commercial editor Sublime Text (free trial available, more details at http://www.sublimetext.com/) and the free and open editor Atom (https://atom.io/). Atom itself was built using Node.js, has a rich plugin ecosystem, and is the editor used to author all the code from this book. To install Atom, you can follow the instructions available at http://bit.ly/1EiGYwn.

Of course there are many other tools available out there, but these are the ones that I personally found useful for learning how to build JavaScript applications.

You can execute all the examples from this book without having to install or configure anything just by using Cloud9 IDE (free registration required) at the project address https://ide.c9.io/alexpop/underscorejs-examples.

Testing JavaScript code with Jasmine

Maintaining complex JavaScript codebases is challenging due to the dynamic nature of the language and the lack of built-in module support (up until ES6). Applying unit testing practices helps alleviate these issues and JavaScript as a language benefits from a large number of unit testing frameworks, libraries, and tools.

We will now add tests for the previous example found in the underscore.map.reduce-with-local-dependencies folder from the source code for this chapter. To implement these tests we will use Jasmine, a popular test framework.

Jasmine is a behavior-driven development (BDD) framework that contains extensive built-in functionality to define and execute tests for JavaScript code. A BDD framework differs from other test frameworks such as QUnit by defining tests as a desired behavior, where the test outcome is specified first followed by the actual test assertion. Jasmine uses a describe/it syntax to define test specifications, while other BDD frameworks use a given/when/then syntax. Using BDD tests produces output similar to a specification document and these types of tests are usually called specs. Other advantages of using Jasmine are that it does not rely on any other library, it has a rich functionality for defining tests and tests assertions, and it has great documentation available at http://jasmine.github.io.

Jasmine introduction

A typical Jasmine test that asserts the result of a trivial JavaScript operation will have the following code (with the Jasmine specific functions highlighted):

describe("A basic JavaScript add operation", function() {
  it("should be correct", function() {
    var result = 1 + 1;
    expect(result).toEqual(2);
  });
});

When running the test, its output should read A basic JavaScript add operation should be correct, forming a meaningful statement about the value delivered by the code being tested. The describe call is a Jasmine global function that will group one or more test specifications that are defined by the it function (which is also another Jasmine global function). Both functions have a test-related description as the first argument. The second argument is a function that defines the test suite in its body with the test specification (or the spec) defined in the it function. Test assertions use the Jasmine global function expect, which is chained with a helper function called matcher that will facilitate the test result evaluation.

There are a couple of built-in matcher functions available, such as toBe(), which checks whether the test assertion object and the expected object are the same; toEqual(), which checks whether the two objects are equivalent; and toBeDefined(), which checks whether the test assertion object is not undefined. You can also define your own custom matchers for more complex expectation checks. Jasmine allows you to set up and tear down data before and after a spec is executed through the global functions beforeEach() and afterEach().

Adding tests using the default Jasmine infrastructure

Before creating the tests, we need to modify the awardAgeCalculator.js file that contains the code under test (or SUTsystem under test) and ensure it is testable. A SUT is testable if it allows swapping out its dependencies, if it can be tested in isolation and does not depend on a shared or global application state.

For our example, we need to test that the two global accessible (or public) functions of the awardAgeCalculator object (the SUT) are producing the expected results when executed against specific data sets. Currently, we cannot easily swap out the default array of people used in the example and we need to change it by making the getPeople() function public and changing the rest of the functions to accept an input array as highlighted in the next code snippet:

var awardAgeCalculator = (function() {
  "use strict";

  var getPeople = function() {
    return [{
      name: "Herta Muller",
      birthYear: 1953,
      awardYear: 2009
    }, {
      ...
    }, {
      name: "Patrick Modiano",
      birthYear: 1945,
      awardYear: 2014
    }];
  };

  return {
    getPeople: getPeople,
    calculateAwardAgeForPeople: function(people) {
      return _.map(people, function(person) {
        return {
          name: person.name,
          awardAge: person.awardYear - person.birthYear
        };
      });
    },
    getAverageAwardAgeForPeople: function(people) {
      var peopleWithAwardAge = this.calculateAwardAgeForPeople(people);
      return _.reduce(peopleWithAwardAge, function(memo, person) {
        return memo + person.awardAge;
      }, 0) / peopleWithAwardAge.length;
    }
  };
}());

We also exposed the getPeople() function to the global scope for convenient access to the default data set. By making these changes, we have created a testable SUT where we can alter the input data for the two functions we plan to test. We can now write the tests by creating a spec\awardAgeCalculatorSpec.js file and using the following code:

describe("Given awardAgeCalculator", function() {
  describe(
    "when calling calculateAwardAgeForPeople()",
    function() {
      var people;
      var peopleWithAwardAge;
      beforeEach(function() {
        people = awardAgeCalculator.getPeople();
        peopleWithAwardAge = awardAgeCalculator.calculateAwardAgeForPeople(people);
      });
      it(
        "then the award age for the first person should be correct",
        function() {
          expect(peopleWithAwardAge[0].name).toEqual("Herta Muller");
          expect(peopleWithAwardAge[0].awardAge).toEqual(56);
        });
      it(
        "then the award age of the last person should be correct",
        function() {
          expect(peopleWithAwardAge[peopleWithAwardAge.length - 1].name).toEqual("Patrick Modiano");
          expect(peopleWithAwardAge[peopleWithAwardAge.length - 1].awardAge).toEqual(69);
        });
    });
  describe(
    "when calling getAverageAwardAgeForPeople()",
    function() {
      var people;
      var aveargeAwardAge;
      beforeEach(function() {
        people = awardAgeCalculator.getPeople();
        aveargeAwardAge = awardAgeCalculator.getAverageAwardAgeForPeople(people);
      });
      it("then the average award age should be correct", function() {
        expect(Math.floor(aveargeAwardAge)).toEqual(69);
      });
    });
});

The tests are defined within two nested describe functions and we used a beforeEach function to avoid code duplication when exercising the SUT. The expectations for the first set of tests are verifying that the person name and the award age are correct.

To execute these tests, we need to add Jasmine support to our example. We will use Bower to install Jasmine as a development package (a package that can be omitted when the current project is deployed to a target environment) through the following command:

bower install jasmine#2.3.4 --save-dev

We will change the default SpecRunner.html file provided with the standalone Jasmine distribution at http://bit.ly/1EhdgHT to reference the files from the Bower package together with the SUT file (the code file) and the test file as highlighted in the following code:

<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Jasmine Spec Runner v2.3.4</title>
  <link rel="shortcut icon" type="image/png" href="bower_components/jasmine/images/jasmine_favicon.png">
  <link rel="stylesheet" type="text/css" href="bower_components/jasmine/lib/jasmine-core/jasmine.css">
  <script type="text/javascript" src="bower_components/jasmine/lib/jasmine-core/jasmine.js"></script>
  <script type="text/javascript" src="bower_components/jasmine/lib/jasmine-core/jasmine-html.js"></script>
  <script type="text/javascript" src="bower_components/jasmine/lib/jasmine-core/boot.js"></script>

  <!-- include source files here... -->
  <script src="bower_components/underscore/underscore.js"></script>
  <script type="text/javascript" src="awardAgeCalculator.js"></script>
  <!-- include spec files here... -->
  <script type="text/javascript" src="spec/awardAgeCalculatorSpec.js"></script>
</head>
<body>
</body>
</html>

Notice that we referenced Underscore as a SUT dependency and we don't need any special test output code to display the results other than ensuring that all required JavaScript files are referenced in the SpecRunner.html file. You can find the example in the underscore.map.reduce-with-jasmine folder from the source code for this chapter.

To run the tests, we just need to open the SpecRunner.html file in a browser and we should see this output:

Adding tests using the default Jasmine infrastructure

Jasmine tests can also be executed automatically through test runners such as Karma (http://karma-runner.github.io/) or Node.js build tools such as Grunt or Gulp. We will discuss these topics in Chapter 5, Using Underscore.js in the Browser, on the Server, and with the Database and Chapter 6, Related Underscore.js Libraries and ECMAScript Standards.

Summary

This chapter provided an introduction to Underscore and explored useful practices and patterns that will be used throughout the book. We established a development workflow for working efficiently with Underscore examples and we finished the chapter by introducing testing with Jasmine.

Based on these fundamentals, in the next chapter, we will start exploring the Underscore functionality for collections in detail.

Left arrow icon Right arrow icon

Description

Underscore.js is one of the most popular modern JavaScript libraries used for functional programming. It can be used as a base for building complex JavaScript applications in a sustainable manner and for building other JavaScript libraries. It embraces functional programming principles but is not opinionated and can be used with imperative, object-oriented, functional, or other programming styles. This book explores how to use Underscore.js to power your code and understand modern JavaScript development concepts while applying a lightweight and efficient workflow to build applications. The book starts with an incremental Underscore.js introduction by exploring key JavaScript concepts. You will then explore the basic features of Underscore.js in action and establish a lightweight development workflow that allows the provided examples to be guided by tests. The book then covers the functionality of Underscore.js with in-depth examples and explanations for understanding and applying the Underscore.js API. You'll also learn how to use Underscore.js as a base for your own modules and libraries within an object-oriented or functional programming style, and will be able to explore Underscore.js use cases in different environments. Eventually, you'll learn about libraries that are closely related with Underscore.js, how to share code between client and server, and how to prepare for the upcoming JavaScript standard ECMAScript 6.

Who is this book for?

If you are a developer with fundamental JavaScript knowledge and want to use modern JavaScript libraries to extend your functional programming skills, then Underscore.js is an important library you should be familiar with.

What you will learn

  • Reference and call Underscore.js functions using a modern JavaScript development workflow
  • Apply Underscore.js to JavaScript arrays, objects, and functions
  • Take advantage of objectoriented or functional programming techniques with Underscore.js
  • Leverage Underscore.js to create code that targets client, server, or database contexts
  • Extend Underscore.js functionality with other closely related libraries
  • Reuse Underscore.jsbased code between client and server applications
  • Prepare for the upcoming JavaScript standard ECMAScript 6 and support older browsers
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Oct 30, 2015
Length: 224 pages
Edition : 1st
Language : English
ISBN-13 : 9781784393816
Languages :

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Publication date : Oct 30, 2015
Length: 224 pages
Edition : 1st
Language : English
ISBN-13 : 9781784393816
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 114.97
React.js Essentials
$32.99
Learning UnderscoreJS
$48.99
Javascript Unlocked
$32.99
Total $ 114.97 Stars icon

Table of Contents

8 Chapters
1. Getting Started with Underscore.js Chevron down icon Chevron up icon
2. Using Underscore.js with Collections Chevron down icon Chevron up icon
3. Using Underscore.js with Arrays, Objects, and Functions Chevron down icon Chevron up icon
4. Programming Paradigms with Underscore.js Chevron down icon Chevron up icon
5. Using Underscore.js in the Browser, on the Server, and with the Database Chevron down icon Chevron up icon
6. Related Underscore.js Libraries and ECMAScript Standards Chevron down icon Chevron up icon
7. Underscore.js Build Automation and Code Reusability Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.6
(5 Ratings)
5 star 60%
4 star 40%
3 star 0%
2 star 0%
1 star 0%
SuJo Dec 25, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book was very easy to digest and follow along, all of the information is organized rather well. I appreciated the paradigm on OOP programming, and I really can't fault the book much. It was probably just too short for my taste, and I would have loved to see an overall project worked during the course of the book. But I felt confident in reading and doing that I can put the puzzle pieces together for myself.Packt has a global $5 ebook sale right now so sorry Amazon I had to buy it there.
Amazon Verified review Amazon
ruben Dec 26, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Excelent resource Learning UnderscoreJSVery interesting book, I understand very simple this tool for programming the applications in JavaScript, the book is well-organizedin all the chapters. I cover the main points to start developing Software with this new library in Java Script software.The book starts with an incremental Underscore.js introduction by exploring key JavaScript concepts. You will then explore the basic features of Underscore.js in action and establish a lightweight development workflow that allows the provided examples to be guided by tests. The book then covers the functionality of Underscore.js with in-depth examples and explanations for understanding and applying the Underscore.js API. You'll also learn how to use Underscore.js as a base for your own modules and libraries within an object-oriented or functional programming style, and will be able to explore Underscore.js use cases in different environments.Ruben.
Amazon Verified review Amazon
Perry Nally Dec 30, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Learning Underscore.js is a perfect introduction to functional programming and ECMAScript 5. I learned faster through comparing what I already knew in regular Javascript with the same function using Underscore.js methods. Underscore.js is very powerful and I'm excited to make use of it in my own sites. Though ECMAScript 6 is almost out, you'll still be able to use Underscore.js, but look for the updated Underscore.js library at that time.I can see why frameworks that use Underscore.js, like Backbone.js, are so popular. Learning Underscore.js is an easy read with concepts plainly described for beginner and veteran js developers.
Amazon Verified review Amazon
Winston Dec 30, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
This book is not for the javascript NOOB. Underscore.js is a JavaScript library which provides utility functions and POWER for common programming tasks like those found in popular languages like Ruby. The author does a great job of explaining the Underscore library and its uses throughout the book. Readers will benefit from the authors explanation of Underscore.js in a test driven environment. Great book to get started.
Amazon Verified review Amazon
Dustin Marx Dec 16, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
"Learning Underscore.js" provides a comprehensive introduction to the JavaScript library Underscore.js. The book consists of seven chapters spanning approximately 200 substantive pages. The first few chapters introduce Underscore.js and cover the majority of its features. The fourth chapter looks at applying Underscore.js with object-oriented and functional paradigms and the fifth chapter describes applying Underscore in the contexts of web browser, server (Node.js), and database (MongoDB and PostgreSQL). The sixth chapter describes Underscore's relationship to other libraries such as Underscore-contrib and Babel and Underscore's relationship to the ECMAScript specification. The final chapter looks at using Underscore applications with other JavaScript tools and frameworks such as CommonJS, Browserify, Jasmine, and Gulp to build, deploy, and test Underscore applications."Learning Underscore.js" covers more than just Underscore.js. It also briefly describes lodash and it discusses the emerging ECMAScript 6 implementations and how Underscore pertains to ECMAScript 5 and ECMAScript 6 applications.There are numerous code listings in "Learning Underscore.js" that are black text on white background with no color syntax and no line numbers in the PDF version of the book Packt Publishing provided to me. I recommend downloading the code separately to use your favorite editor or IDE to view the code or use the Cloud9 links referenced in the book to view the code. The book provides numerous references to additional resources (many of which are freely available online) with additional background details and specific topics."Learning Underscore.js" is an introductory book that manages to provide a comprehensive introduction to Underscore.js and explains Underscore's relationship to the ECMAScript specifications and the future of JavaScript.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the digital copy I get with my Print order? Chevron down icon Chevron up icon

When you buy any Print edition of our Books, you can redeem (for free) the eBook edition of the Print Book you’ve purchased. This gives you instant access to your book when you make an order via PDF, EPUB or our online Reader experience.

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
Modal Close icon
Modal Close icon