El método .data() en jQuery

26 Mar 2011

Introducción

Desde la versión 1.4.3, jQuery nos permite asociar cualquier tipo de datos a un elemento del DOM o colección de ellos, para reutilizarlos en cualquier punto de un script evitando agujeros de memoria.

La sintaxis es muy sencilla:

.data( key, value );

Donde:

key (cadena String) es el nombre del dato que queremos guardar.
value es el nuevo valor. Puede corresponderse con cualquier tipo Javascript, incluyendo arrays y objetos.

También podemos asignar varios valores al mismo tiempo pasando al método data un objeto compuesto de pares clave-valor:

.data( obj );

Donde:

obj se corresponde con un objeto Javascript formado por pares con el nombre del dato y su correspondiente valor.

Ejemplo simple de asignación de datos

Pensemos en un escenario donde necesitamos asignar un determinado estado a un elemento del DOM.

$( '#user_mail' ).data( 'status', 'send' );
 
console.log( $( '#user_mail' ).data( 'status' ) ); // send

Este dato se puede actualizar en cualquier momento para reflejar un cambio de estado:

$( '#user_mail' ).data( 'status', 'waiting' );

Como el método nos permite asignar cualquier tipo de objeto Javascript, podemos establecer un estado más complejo a nuestro ejemplo:

$( '#user_mail' ).data( 'status', {
  to : 'info@anyaddres.com',
  subject : 'My Subject',
  mailCotent : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
  response : 'send'
} );

El atributo data en HTML5

Una de las novedades de HTML5 es la posibilidad de utilizar el atributo data para asignar valores personalizados a una etiqueta. Esto permite solucionar el uso de pseudo-attrs no validados por el W3C que tantas veces encontramos en aplicaciones y plugins:

<div id="myLayer" role="something" flag="something_more"></div>

En HTML5, el ejemplo anterior quedaría como sigue:

<div id="myLayer" data-role="something" data-flag="something_more"></div>

Incluso podemos preparar los datos con objetos Javascript para reutilizarlos más adelante:

 <div id="myLayer" data-role="page" data-options='{ "site" : "etnassoft", "category" : "javascript" }'></div>

NOTA: Para facilitar el posterior manejo de los datos es interesante preparar la cadena con dobles comillas utilizando así para el valor de la tag las comillas simples.

Integrando el atributo data de HTML5 con jQuery

Desde la versión 1.4.3 de jQuery, el atributo HTML data se integra directamente con la librería aprovechando con ello los recursos nativos del lenguaje.

Retomando el ejemplo anterior, el siguiente código funciona como se espera:

console.assert( $('#myLayer').data('role') === "page" );
console.assert( $('#myLayer').data('options').site === "etnassoft" );

NOTA: Para comprobar los resultados, hemos utilizado el método de assert de la consola de Firebug. Para más información, puede revisarle el artículo «Consola de Firebug al Detalle«.

Consideraciones sobre el rendimiento de data en jQuery

Un aspecto negativo de este útil método es que jQuery guarda los datos internamente en el objeto $.cache(). Esto quiere decir que, como pudimos comprobar cuando medimos el rendimiento de los arrays frente a los objetos en Javascript, resulta más lento en Firefox (al menos hasta su versión 4.0).

Echemos un vistazo a la estructura de datos almacenada. Vayamos a una página que utilice jQuery (como la oficial) y abramos una consola en Firebug:

var $body = $( 'body' );
var $logo = $('#jq-siteLogo');
 
$body.data( 'foo', 'Hello World' );
$body.data( 'bar', 'La donna e mobile' );
$logo.data( 'status', 'works' );
console.log( $body.data( 'foo' ) );
 
console.dir( $.cache );

Si bajamos hasta el final del árbol devuelto, encontramos nuestros datos:

23 Object { foo="Hello World", bar="La donna e mobile"}
24 Object { status="works"}

Como comprobamos, son objetos en lugar de arrays: esto penaliza de forma significativa en Firefox.

Además de este detalle, podemos medir el rendimiento del método data de jQuery con la asignación y lectura del método attr, el cual puede realizar una labor similar.

Tomemos por ejemplo los siguientes códigos:

var theInput = $('#myInput');
 
// Attr set
theInput.attr('someAttr', 'newValue');
 
// Attr get
theInput.attr('someAttr');
 
// Data set
theInput.data('someData', 'newValue');
 
// Data get
theInput.data('someData');

Vamos a comprobar qué métodos son más rápidos en términos de acceso y escritura para jQuery. El estudio comparado para este caso lo podemos encontrar en aquí.

La tabla generada a día de hoy, muestra los siguientes resultados:

jQuery Data vs Attr

Los datos, y los de sus revisiones 2 y 5, son claros: el atributo data penaliza considerablemente frente al attr en casi un 200%.

Es un factor importante a tener en cuenta para aquellas aplicaciones más pesadas o que necesitan de un entorno muy optimizado (por ejemplo los dispositivos móviles).

Conclusión

El método .data() ofrece una interesante ayuda para los desarrolladores de aplicaciones Javascript que necesitan de almacenar datos en los elementos del DOM si tener que recurrir a pseudo-tags. También es una forma sencilla de manejar el mismo atributo en aquellos proyectos basados en HTML5 que lo implementen.

Sin embargo, como casi todas las grandes funcionalidades en Javascript, tiene un coste en rendimiento importante que hay que sopesar. Para aplicaciones sencillas o que no precisan de medir hasta el último milisegundo, puede ser la solución perfecta. En aquellos entornos más exigentes, como el de las aplicaciones para dispositivos móviles, quizá lo más recomendable sea volver al almacenamiento más tradicional mediante arrays u objetos simples.

Más:

Aún no tenemos debug!
Ningún marciano se ha comunicado.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *