Sobrecarga de funciones en Javascript

  • Por
  • y  
Cómo realizar lo que se conoce como Sobrecarga de funciones en el lenguaje Javascript, un concepto usado en la Programación Orientada a Objetos que no es exactamente igual en Javascript.

Comenzamos con este artículo una serie de entregas dedicadas a "Buenas prácticas en Javascript" que nos servirán para entender un poco mejor algunas de las cosas que se pueden hacer en el lenguaje para mejorar nuestra programación.

El desarrollo web ha cambiado mucho en los últimos años y ahora es casi imprescindible tener un relativo dominio de Javascript para hacer un buen trabajo, nos dediquemos a lo que nos dediquemos dentro del desarrollo. Javascript ya no es el lenguaje que utilizamos para comprobar un formulario y ver si está todo correcto, sino que ahora, con una serie de frameworks como Angular, Backbone, Ember, etc. se nos abren muchas posibilidades nuevas.

Javascript es un lenguaje orientado a objetos serio que nos sirve para hacer grandes cosas, con el que realmente se pueden crear aplicaciones de todo tipo. Tanto es así que Javascript ha entrado en el mundo backend de la mano de NodeJS, un terreno vedado hasta entonces, ya que no existía método de usar Javascript del lado del servidor.

Nota: Este texto es una transcripción, no literal, de un interesante hangout impartido por Eduard Tomàs, que nos dejó muchas claves para entender Javascript, un lenguaje que tiene muchas cosas malas, pero también muchas cosas buenas. Para saber valorar Javascript y "amarlo", necesitamos entenderlo y en este programa #jsIO sobre buenas prácticas en Javascript que ahora estamos transcribiendo nos ayudará sin duda a ello.
El programa también está motivado por una serie de conceptos que los programadores en lenguajes más tradicionales entienden, pero no tratados exactamente igual en Javascript. Por eso, quien viene de lenguajes como PHP, C#, Java, quizás se encuentra con algunas confusiones cuando se aproxima a Javascript. Es el caso de clases, objetos, la variable "this" y el contexto, etc.

Durante el hangout se habló de muchas cosas interesantes. En este artículo abordaremos la sobrecarga de funciones en Javascript y veremos que en Javascript también se puede realizar, si conocemos algunos de los mecanismos del lenguaje.

Sobrecarga de funciones

No existe la sobrecarga de funciones en Javascript. Esto puede percibirse como una carencia en el lenguaje, pero es que realmente Javascript tiene otro mecanismo que, si quieres entenderlo así, puede incluso considerarse más potente. En resumen, se trata de lo siguiente: una función en Javascript puede ser llamada con cualquier número de parámetros, con independencia de los que se defina.

Es que Javascript puede invocar una función con cualquier juego de parámetros. Es decir, puedo declararla con un número de parámetros dado, pero puedo invocarla con cualquier otro conjunto de parámetros que quiera o necesite.

Si no coinciden los parámetros, no es considerado ningún error en el lenguaje, simplemente el intérprete hará lo que pueda para adaptarse a esa manera de invocarla. La situación será la siguiente:

  • Si faltan parámetros, su valor será "undefined". Por ejemplo, si tengo una función definida con dos parámetros y al invocarla sólo defino el valor de uno de ellos, el segundo parámetro tendrá este valor.
  • Si le sobran, puedo acceder a los parámetros restantes a través de "arguments". El objeto arguments está siempre disponible dentro de la función y contiene todos esos parámetros que se le han pasado a la función cuando fue invocada.

Valores por defecto de los parámetros en funciones

En Javascript no existe el típico mecanismo que conocemos en otros lenguajes más tradicionales, en el que las funciones pueden tener parámetros con valores por defecto, pero realmente podemos asignar esos valores por defecto de otra manera. Se hace dentro del código de las funciones y está basado en esta sintaxis:

undefined || {algo} === {algo}

Este pedazo de "pseudocodigo" nos dice que undefined o {algo} es exactamente igual a {algo}. Pero lo vamos a ver mucho mejor con un código real.

var mivariable = undefined || 45
console.log(mivariable);

Como se puede ver, estamos definiendo una variable y el valor que le asignamos es undefined o 45. Pues entonces, el valor de mi variable será siempre 45. Lógicamente, aquí sigue sin tener mucho sentido, porque el valor de undefined es siempre indefinido y 45 es otro literal, pero lo podemos aplicar para definir valores por defecto en los parámetros de la siguiente manera:

function f(param){
   var variable = param || 10;
   console.log(variable);
}

En esta función tenemos un parámetro "param". En la primera línea definimos una variable llamada "variable" a la que le asignamos el valor de parámetro "param" o el literal 10.

Recordemos que a la función podemos invocarla enviando o no el valor de ese parámetro con el que fue declarada. Si no lo enviamos, simplemente el parámetro tiene como valor undefined. De este modo, al crear la variable "variable", si "param" era undefined, pues simplemente se le asignará el valor 10.

Si llamamos la función con distintos juegos de parámetros:

f(80);
f();

En el primer caso nos mostraría 80 por consola y en el segundo nos mostraría 10, que es el valor por defecto, ya que no se le ha pasado ningún parámetro.

Objeto arguments o "array" de arguments

Dentro de una función, sin que tengas que definir nada, existe un objeto llamado arguments que te servirá para acceder a todos los parámetros que puedan invocarse en la función que estás definiendo. En la variable arguments encontrarás un número variable de casillas, dependiendo del número de parámetros con el que se invoque cada vez a la función.

Nota: arguments es realmente un objeto, pero muchos programadores lo tratan como si fuera un "array" y eso no está mal. De hecho, a veces por simplicidad, podemos referirnos a arguments como array, a pesar que realmente en Javascript es un objeto. En verdad, es un objeto donde todos sus índices son númericos y en nuestra programación lo podemos tratar tranquilamente como si fuera un simple array, abstrayéndonos de que internamente Javascript lo define como un objeto.

function args(){
   	console.log(arguments);
   	console.log(arguments.length);
}

Como ves, lanzamos un par de mensajes a la consola, sencillos, simplemente para mostrar el contenido de arguments y luego para saber el número de parámetros en la invocación de la función.

Luego podemos invocar a la función con varios juegos de parámetros:

args();
args(2);
args("gol", "sol", "remo", 445);

Como verás, si pones ese código en ejecución, en arguments encontrarás cada uno de los valores de esos parámetros y en "arguments.length" el número de parámetros de cada invocación.

Ejemplo de sobrecarga de funciones

Con todo lo que has aprendido, puedes crear funciones que acepten cualquier número de parámetros e implementar los valores por defecto que necesites.

Nota: Todos estos mecanismos son los que permiten a librerías como jQuery invocar a las funciones pasando como parámetro distintos juegos de valores. Lo podemos combinar con el operador "typeof()" si lo necesitamos para saber qué tipos son los parámetros que estamos recibiendo, por si queremos hacer cosas diferentes con los parámetros dependiendo del tipo.
typeof(33); //nos devolverá number
typeof("hola); //nos devolverá string

Solo para probar lo aprendido en este artículo, vamos a ver un ejemplo de sobrecarga que nos permite sumar un número indeterminado de parámetros. Lógicamente, solo puedo sumar los parámetros que tengan valores numéricos.

function sumar(){
   var suma = 0;
   for(var i=0; i<arguments.length; i++){
      if(typeof(arguments[i])=="number"){
         suma += arguments[i];
      }else{
         console.log("no puedo sumar ", arguments[i], " porque es un ", typeof(arguments[i]));
      }
   }
   return suma;
}

A esta función podríamos llamarla con cualquier número de parámetros, de un modo como este:

sumar(34, ["kk", "jj"], 3, "hola", 3.5); //nos devolverá 40.5

Con esto acabamos este artículo sobre sobrecarga de funciones en Javascript. Hemos llegado tan solo al minuto 17 del Hangout de Buenas prácticas en Javascript #jsIO, que os recomendamos ver para seguir aprendiendo. En futuras entregas iremos cubriendo otros de los conceptos que se explicaron aquel día.

Autor

Miguel Angel Álvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Autor

Eduard Tomàs

Apasionado de la informática, los videojuegos, rol y... la cerveza. Key Consultant en Pasiona y MVP en #aspnet

Compartir

Comentarios

Adrián

26/12/2013
Función sumar()
En primer lugar, un artículo muy interesante, pero en segundo lugar: ¿No falta código en la función sumar() ( justo donde empieza el for)?

Un saludo.

YeanKarlo

02/1/2014
Función completa del excelente artículo
De acuerdo con mi punto de vista, la función completa es la siguiente:

function sumar()
{
var elementos = arguments.length;
var suma = 0;
for(var i=0; i<elementos; i++)
{
if (typeof(arguments[i]) == "number")
{
document.write("<br>");
document.write("Elemento sumado: " + arguments[i]);
suma += arguments[i];
}
}
return suma;
}

Saludos !!!! :-)