¡Hola a todos! Este es mi primer tutorial para este sitio, del cual estoy muy orgulloso de formar parte, y espero poder compartir todo lo que voy aprendiendo día a día con vosotros a lo largo de, espero, mucho tiempo. Para empezar os traigo un un pequeño tutorial bastante técnico. Un patrón de diseño que os ayudará a optimizar vuestro código Javascript y que seguro, os parecerá interesante a los que no lo conozcáis.

Autor:

Intentando mejorar cada día en este mundo tan cambiante de la programación. Sígueme en Twitter o en GitHub. Actualmente estoy disponible para contratar.
Descarga Demostración

Introducción: Funciones perezosas, ¿de qué me hablas?

Antes de nada comentaros que, como he mencionado antes, este tipo de funciones es un patrón de diseño, no se trata de ningún tipo de función especial de javascript ni nada por el estilo. Con este patrón lo que conseguiremos será reducir altamente la ejecución de nuestro código Javascript, ya que hará que las funciones que lo implementen trabajen lo mínimo posible, de ahí su nombre perezosas. Lógicamente, como todo patrón de diseño, sólo puedes implementar las funciones perezosas cuando se da el siguiente caso:

Una función puede implementar el patron de función perezosa cuando una vez que se evalúa su contenido, devolverá el mismo valor de retorno en las próximas llamadas.

Aquí lo primero que pensaréis es, si una función devuelve siempre lo mismo llamada tras llamada, no tiene mucho sentido, pues las funciones suelen ser trozos de código dinámicos que devuelven unos valores u otros según se evalúa su código interno. Pero esto no es así siempre; en javascript por ejemplo, es muy habitual comprobar que navegador está usando el cliente para hacer unas tareas u otras.

Este es el ejemplo típico de función perezosa, pues una vez que la función evalúa que está, por ejemplo, en Firefox, las proximas llamadas, devolverán siempre lo mismo, pues el navegador no cambia. A continuación un par de ejemplos.

Ejemplo 1: Comprobando el navegador del usuario

Para hacerlo más interesante y útil, vamos a crear una función que detecte si el navegador actual del usuario es una versión de Internet Explorer. Antes de conocer las funciones perezosas, este código sería el que seguramente haríamos:

function esIE(){
    return navigator.userAgent.toLowerCase().indexOf("msie")>-1;
}

Vale, el código funcionará correctamente, pero para cada llamada tendrá que evaluar la expresión, lo cual no quiere decir que vaya a ir lentísimo, pero ten en cuenta que al final todo suma y en webs grandes estes pequeños detalles se pueden llegar a notar.

Una vez que sabes que es o no es Internet Explorer, el resultado de llamar a la función será siempre el mismo(true para los navegadores Internet Explorer y false para el resto). Por lo tanto, vamos a implementar el patrón de funciones perezosas para que dicha comprobación solo se haga la primera vez.

function esIEPerezosa(){
    /*Obtiene el valor que va a ser retornado siempre*/
    var esIE = navigator.userAgent.toLowerCase().indexOf("msie")>-1;
    /*Sobreescribe la función para que retorne siempre el valor obtenido*/
    esIEPerezosa = function(){
        return esIE;
    }
    /*Para la primera llamada, vuelve a llamar a la funcion ya sobreescrita*/
    return esIEPerezosa();
}

Una función perezosa siempre va a estar formada por tres partes:

  • 1. Evaluar una serie de cálculos y expresiones para dar con el valor que va a devolver siempre.
  • 2. Sobreescribirse a si misma. Esta es la esencia de este patrón, en Javascript, al ser tan dinámico, se permite que una función se sobreescriba a si misma, de modo que en este caso se sobreescribe a sí misma para retornar siempre el valor obtenida en el paso 1
  • 3. Llamarse a sí misma para devolver un valor la primera vez que se llama a la función.

El patrón de función perezosa siempre consta de tres pasos: Evaluar, Sobreescribirse y Autollamarse.

Ejemplo 2: Extraer una variable de configuración

Este es un caso que se me ha ocurrido ahora de entre otros muchos que me podrían haber salido, lógicamente, no tiene un uso general. Por ejemplo, imagínate que por la razón que sea, estás cargando ciertos datos en el documento y necesitas extraerlos. Si sabes que estes datos no van a cambiar, es un escenario perfecto para el patrón:

function getTitleText(){
    /*Buscamos el valor que va a devolver siempre*/
    var element = document.getElementById("label");
    if(element){
        /*Sobreescribe la función*/
        getTitleText = function() { return element.innerHTML; }
        /*Se llama a sí misma para la primera vez*/
        return getTitleText();
    }
    return "";
}

Como podéis comprobar,en este ejemplo se siguen los pasos comentados anteriormente: evaluar, sobreescribir y autollamar

Conclusión

La funcion perezosa es un patrón de diseño que nos ayudará a mejorar el rendimiento de ciertas funciones Javascript y que como habéis visto, no necesita ningún tipo de conocimiento de UML ni nada por el estilo.

Ahora que lo conocéis, de vosotros depende que seáis capaces de ver en que casos reales lo podréis utilizar, lo cual suele costar un poco al principio, pero que seguro poco a poco os saldrá solo ;) .

¿Necesitas desarrollar un proyecto web o para móviles? ¡Estamos disponibles!

Visitar Cokidoo

Cokidoo, los creadores de Ontuts, desarrollamos proyectos tecnológicos centrados en redes sociales y aplicaciones web, aplicaciones móviles y consultoría web y bases de datos.

Somos jóvenes, inquietos, versátiles, apasionados por la innovación y enfocados en las nuevas tecnologías. Con Ontuts tratamos de compartir nuestro conocimiento adquirido en los distintos proyectos, ayudando a la comunidad y mostrando nuestra capacidad tecnológica.

Si necesitas un presupuesto sin compromiso, estamos disponibles, no dudes en contactar con nosotros.

Comentarios en esta publicación (6 comentarios)

¿Te ha gustado esta publicación? ¡Puedes compartir tu opinión con todos nosotros! Simplemente pincha aquí mismo.

Muy buen tuto! Me encanta el ejemplo que has usado. En http://www.erasmusu.com nos ha venido de perlas el no tener que recomprobar continuamente el navegador para cargar un CSS u otro :)

Llevo años programando en javascript, y jamás había oído hablar de las funciones perezosas. Me parecen una gran técnica. ¡Muchas gracias!

Emilio

Yo tampoco lo había oído nunca, muy úil Iván.

El caso de los navegadores es perfecto!

¿Qué tal crear variables como funciones que almacenen este tipo de información?
Por ejemplo, usando jQuery….

var msie = ( jQuery.browser.msie ) ? true : false;
var msie = {
msie6 : ( jQuery.browser.version == ’6.0′ ) ? true: false,
msie7 : ( jQuery.browser.version == ’7.0′ ) ? true: false
}

… y luego…

jQuery(document).ready(function($){
if (msie.msie6) {
// acciones específicas para explorer 6
}
})

@felipe.tv El ejemplo que estás poniendo es totalmente válido, pero en tu caso se está haciendo la comprobación 2 veces, y si hubiese más versiones todavía habría más expresiones de comprobación.
Lo que hacen las funciones perezosas es simplemente trabajar lo mínimo posible, es decir, solo una vez :)

¡Un saludo y gracias por tu aporte!