Descubriendo Underscore.js

En mi primer post en showmethecode voy a tratar de descubrir underscore.js, sus ventajas y su potencia.

Introducción

Progresivamente,  javaScript está evolucionando dejando de ser un lenguaje de programación destinado exclusivamente a pequeños scripts incrustados en aplicaciones web. A raíz de este hecho, numerosas herramientas, librerías y frameworks están siendo desarrollados para dotar de robustez y facilidad de uso a este lenguaje tan controvertido.
Una de estas herramientas es Underscore.js. Una librería que, a mi juicio, debe estar presente en cualquier aplicación javaScript independientemente de si el entorno es client-side o server-side.

No pierdas tiempo, esa función ya está desarrollada….

Sus creadores definen undescore.js como:

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.

Bueno…y que significa esto…

Durante el desarrollo de  una aplicación javaScript, puede requerirse cierta funcionalidad de bajo nivel o utilities en la  manipulación de  objetos, funciones o colecciones. Algunas de  estas necesidades javaScript no las soluciona de  manera nativa o al menos, no en todos los navegadores. Lo que conlleva, en numerosas ocasiones, a la creación de librerías propias de utils o incluso a extender prototypes de objetos nativos como Object o String.

Underscore.js es una librería que ofrece un gran número de funciones (+80) realmente interesantes, en tan solo 4Kb. Es muy probable que gran cantidad de tus necesidades las resuelva por ti, sin necesidad que pierdas tiempo desarrollando código que no tiene nada que ver con tu lógica de negocio.

Undercore en acción

Vamos a ver un pequeño ejemplo de como esta librería nos ahorra trabajo.

Supongamos que tenemos en un array con enteros del 1 al 100 y queremos obtener los que sean mayores de 50.
Nuestro código sería algo parecido a esto:

Veamos ahora como sería el mismo ejemplo utilizando la función filter:

En el ejemplo anterior hemos utilizado la función filter que se encuentra en la especificaciones ECMAScript 5. En este caso, Underscore delegará la ejecución en la implementación nativa si el entorno lo permite. Si por el contrario, no lo estuvise (un navegador antiguo), se ejecutaría una implementación propia de Underscore.

¿Cuándo uso y cuándo no uso Underscore.js?

Mi recomendación: prácticamente siempre. Bueno,  si tu aplicación se va limitar meramente a jugar con los elementos del DOM y a realizar alguna que otra animación, quizá no te haga falta usar nada más que Jquery. Si por el contrario tu aplicación debe manejar estructuras de datos o realizar llamadas AJAX delegando parte de tu lógica de negocio al lado del cliente, Underscore es altamente recomendable.

Getting Started

Para empezar a utilizar simplemente incluye underscore.js y ya está.

Esta librería funciona de manera similar a Jquery, en lo que se refiere al acceso a su funcionalidad, creando un objeto simple en una variable global. Este objeto es el caracter, _.
Al igual que Jquery[$], Underscore permite remapear su caracter [_] si entra en conflicto.

Maneras de trabajar

Existen dos maneras de trabajar con esta librería: object-oriented o functional style. Veamos como sería el ejemplo anterior empleando ambos estilos:

Functional style

Object-oriented style

Ambos dan el mismo resultado. A pesar de que en la documentación oficial, los ejemplos están realizados con funcional style, depende de tus preferencias el utilizar un estilo u otro.

Funcionalidades

Underscore implementa 80 funciones primitivas divididas en cinco grupos dependiendo su naturaleza:

  • Collections
  • Arrays
  • Objects
  • Functions
  • Utilities

Como describir cada una de las 80 funciones sería demasiado extenso y farragoso, voy a explicar un par de mis ejemplos favoritos de cada uno de los grupos.

Collections

Se considera una Collection a un array o un objeto. Underscore provee un gran número de funciones que pueden ser utilizados en ambos. Ya hemos visto en el ejemplo de antes la función filter, ahora veamos otros ejemplos.

where

Supongamos que tenemos un array que contiene objetos de tipo cliente con su nombre, ciudad y edad y queremos hacer una búsqueda por ciudad. Con el método where seria tan sencillo como lo siguiente:

sortBy

Continuando con el ejemplo anterior. Imaginemos que además ordenar por edad. La función sort ordena una colección según la condición que le indiquemos.

Como hemos visto, resulta realmente sencillo filtrar y ordenar colecciones según criterios. A parte de estos dos métodos, Underscore ofrece de manera sencilla métodos para trabajar con collections, permitiendo (según el caso) delegar parte de la responsabilidad del servidor en el cliente.

Arrays

Underscore tiene una serie de métodos que te permite trabajar con arrays de manera realmente sencilla. Los siguientes ejemplos los encuentro especialmente útiles en algoritmos matemáticos y estadísticos.

unique

Devuelve un array con los valores únicos que están presentes en el array.

difference

Devuelve los valores de un array que no están presentes en los otros arrays.

range

Por último, uno de mis métodos favoritos. El método range permite crear listas de números enteros de manera sencilla, indicando el rango y el incremento. Veamos unos ejemplos.

Objects

Underscore implementa una serie de funciones para el manejo de objetos, que agilizan algunos de los aspectos más controvertidos de javaScript, como la herencia, copia de objetos y comparación de los mismos. Veamos unos sencillos ejemplos de la potencia de los siguientes métodos.

extend

Crea una copia de las propiedades (métodos y atributos) de un objeto source sobre un objeto destino.

El objectA ha extendido la función anotherFunction definida en objectB.

clone

Crea una copia de un objeto. Esta función se debe usar con precaución, ya que si el objeto contiene un array y otro objeto anidado, se crea una copia de la referencia al objeto y no una copia de este.

Este es un ejemplo de como se copian las referencias de objetos anidados.

isEqual

En muchas ocasiones determinar si dos objetos son idénticos no resulta sencillo ya que el operador == y === compara si las referencias apuntan al mismo objeto.

Mediante la función isEqual, podemos saber si dos objetos se pueden considerar iguales.

Functions

Aunque suene redundante, Undescore tiene funciones que trabajan con funciones. A continuación explicaré algunos de los usos que se les puede dar.

throttle

Crea una nueva versión de una función que sólo se ejecuta al menos una vez por cada periodo de tiempo indicado.

En el ejemplo anterior, tenemos asociado una función render a un evento click sobre el navegador. Como la función se ha throttled sólo se ejecutará si, una vez transcurridos 100ms o más, se vuelve a hacer click. Este método es especialmente útil cuando se quiere prevenir que se ejecute un evento repetidas veces.

once

Crea una nueva versión de una función que solamente se ejecuta una vez. Muy útil para funciones de inicialización.

Podemos observar que, aunque se llama consecutivamente a la función initializeOnce, ésta solo se ejecuta una sola vez.

compose

Crea la composición de una lista de funciones, las cuales toman como parámetros los valores devueltos por las anteriores. En términos matemáticos, si tenemos f(),g(),h() producen f(g(h()). Con un ejemplo se entiende mejor el funcionamiento del método compose.

Como vemos, en primer lugar se realiza la operación 4 * 3 = 12 y posteriormente se realiza 12 + 2 = 14.

Utilities

Por último, describiré las utilities que ofrece Underscore.

template

Existe gran variedad de template engines (mustache.js, twig.js,handlebars.js, etc…) que dan para un artículo por si solos y que ya abordaremos en otro momento. Simplemente señalar que underscore.js implementa su propio template engines, opción interesante si no se desea utilizar otra solución. Veamos un sencillo ejemplo:

random

Sencilla pero eficaz. En javaScript, la función random devuelve un number entre 0 y 1. Con Underscore le puedes especificar entre que enteros deseas dicho número aleatorio.

Conclusión

Underscore.js es una muy buena librería que te ayudará, sin duda, a que te centres en la lógica de negocio de tu aplicación sin perder tiempo en desarrollar y testear funciones de más bajo nivel. Además es una librería que no entra en conflicto con ninguna otra, pesa apenas 4Kb (Minified and Gzipped) y que posee una completa batería de test y benchmarks.

Para finalizar, quisiera nombrar la librería underscore.string que complementa a Underscore con +60 funciones de manipulación de Strings.