¿Qué son las funciones variádicas?

Funciones variádicas en JavaScript

Es otra de las características flexibles de este maravilloso lenguaje de programación.
En JavaScript no se necesita ningún truco especial (como la sobrecarga) para hacer que una función reciba un número indeterminado de argumentos, sencillamente, si un argumento no es especificado en el llamado de la función, éste tomará el valor undefined.

Una función variádica es una función de aridad indefinida, es decir, que acepta una cantidad de argumentos variable.

Veamos el siguiente ejemplo:

    function fnMessage (name, message) {
        console.log("\nHola", name);
        console.log(" >", message);
    }
    fnMessage("Jherax"); //1 arg
    fnMessage("David", "JavaScript rules!!"); //2 args
    fnMessage("Coco", "Variadic", "fiction"); //3 args

En el ejemplo anterior vemos que la función fnMessage especifica explícitamente dos argumentos (name, message). La función es llamada 3 veces especificando un número diferente de argumentos, sin embargo en la última llamada nunca capturamos el último argumento, ya que en la definición de la función no fue especificado.

💡 Una solución rápida podría ser el crear una función que especifique la suficiente cantidad de argumentos que podamos llegar a necesitar, y como lo mencionamos anteriormente, no habría problema porque si no se especifica un argumento en el llamado de la función, éste tomará el valor de undefined.😡 Sin embargo ésta solución no es la más adecuada debido a que necesitamos especificar un número determinado de parámetros en la definición de la función, lo cual hace que esta implementación no sea escalable.

🙄 Para solucionar este inconveniente contamos con el objeto especial arguments, el cual es una variable local que disponemos dentro de cualquier función, y contiene todos los argumentos recibidos por la función, empezando con el primer argumento en el índice cero (Array-like).

Rescribiendo la función anterior para que reciba múltiples argumentos…
    function fnMessage (name) {
        var i, length = arguments.length;
        console.log("\nHola", name);
        //recorremos los argumentos, excepto el primero
        for (i = 1; i < length; i += 1) {
            console.log(" >", arguments[i]);
        }
    }
    fnMessage("Jherax");
    fnMessage("David", "JavaScript rules!!");
    fnMessage("David", "JavaScript", "SPA");
Nota: El valor de los elementos en arguments también puede ser modificado…
    function fnMessage (name) {
        console.log("\nHola", name);
        //obtenemos el segundo argumento de la lista
        if (arguments.length > 1) {
            arguments[1] = "Variadic fiction!";
            console.log(" >", arguments[1]);
        }
    }
    fnMessage("Jherax", "...a reemplazar");

A tener en cuenta

❗ El objeto arguments no es realmente un Array, es similar a uno (Array-like), ya que contiene una lista de elementos y posee la propiedad length, pero aparte de eso, no posee ninguna otra de las propiedades definidas en el prototipo de Array, aunque puede ser convertido a un verdadero Array:

    function testArgs () {
        var args = Array.prototype.slice.call(arguments);
        console.log(args);
    }

El objeto arguments posee las siguientes propiedades:

  • arguments.callee: referencia a la función que se está ejecutando.
  • arguments.caller: referencia a la función que invocó a la función en ejecución.
  • arguments.length: referencia al número de argumentos pasados a la función.

Nota: no se recomienda el uso de arguments.callee ni arguments.caller ya que son APIs obsoletas, y no son soportadas a partir de ECMAScript 5 en strict mode. Uno de los principales problemas es que en funciones recursivas, la palabra reservada this obtendrá un valor diferente del contexto en donde se declaró la función recursiva. Recomiendo leer toda la nota sobre arguments.callee — MDN.

😎 Y retomando el código anterior, podemos refactorizar nuestra función así:

    function fnMessage (name) {
        var br = "\n > ";
        //obtenemos desde el segundo argumento en adelante
        var args = Array.prototype.slice.call(arguments, 1);
        console.log("Hola", name + ",");
        console.log(br + args.join(br));
    }
    fnMessage("Jherax", "4", "3", "2", "1");

Conclusión

Las funciones variádicas nos dan la posibilidad de crear funciones tan complejas como necesitemos, por ejemplo en casos en donde el resultado de una operación dependa de la cantidad de parámetros pasados a la función. El ejemplo que utilizamos para este artículo fue diseñar una función variádica que remplace a varias funciones similares pero que especifican diferente cantidad de argumentos.

En este artículo vimos el uso del método call, sin embargo no entramos en detalle.
En JavaScript, las funciones también son objetos, y en su prototipo están definidos los métodos bind, call y apply, los cuales sirven para ejecutar una función en un contexto específico suministrado por el primer argumento, pero de estos métodos hablaré con más detalle en un próximo artículo.

Happy coding!

One thought on “¿Qué son las funciones variádicas?

Comentarios

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s