Muy a menudo necesitamos realizar una acción similar en muchos lugares del script. Por ejemplo, debemos mostrar un mensaje atractivo cuando un visitante inicia sesión, cierra sesión y quizás en otro lugar.
Las funciones son los principales “bloques de construcción” del programa. Permiten que el código se llame muchas veces sin repetición.
Ya hemos visto ejemplos de funciones incorporadas, como alert(message), prompt(message, default) y confirm(question). Pero también podemos crear funciones propias.
Declaración de funciones
Para crear una función podemos usar una declaración de función .
Se parece a esto:
function mostrarMensaje() { alert( '¡Hola a todos!' ); }
La palabra clave function va primero, luego el nombre de la función , luego una lista de parámetros entre los paréntesis (vacío en el ejemplo anterior) y finalmente el código de la función, también denominado «el cuerpo de la función», entre llaves.
Nuestra nueva función puede ser llamada por su nombre: mostrarMensaje().
Por ejemplo:
function mostrarMensaje{ alert( '¡Hola a todos!' ); } mostrarMensaje(); mostrarMensaje();
La llamada mostrarMensaje() ejecuta el código de la función. Aquí veremos el mensaje dos veces.
Este ejemplo demuestra claramente uno de los propósitos principales de las funciones: evitar la duplicación de código.
Si alguna vez necesitamos cambiar el mensaje o la forma en que se muestra, basta con modificar el código en un solo lugar: la función que lo genera.
Variables locales
Una variable declarada dentro de una función solo es visible dentro de esa función.
Por ejemplo:
function mostrarMensaje() { let mensaje = "Hola, yo soy JavaScript!"; // variable local alert( mensaje ); } mostrarMensaje(); // Hola, yo soy JavaScript! alert( mensaje ); // <-- Error! La variable es local dentro de la función
Variables externas
Una función también puede acceder a una variable externa, por ejemplo:
let nombredeUsuario = 'Maria'; function mostrarMensaje() { let mensaje = 'Hola, ' + nombredeUsuario; alert(mensaje); } mostrarMensaje(); // Hello, Maria
La función tiene acceso completo a la variable exterior. Puede modificarlo también.
Por ejemplo:
let nombredeUsuario = 'Maria'; function mostrarMensaje() { nombredeUsuario = "Bob"; // (1) cambió la variable exterior let mensaje= 'Hello, ' + nombredeUsuario; alert(mensaje); } alert( nombredeUsuario ); // Maria antes de la llamada de función mostrarMensaje(); alert( nombredeUsuario ); // Bob, el valor fue modificado por la función
La variable externa solo se usa si no hay una local. Así que una modificación ocasional puede suceder si olvidamos let.
Si se declara una variable con el mismo nombre dentro de la función, ésta sombrea la externa. Por ejemplo, en el código de abajo, la función utiliza el local nombredeUsuario. El exterior se ignora:
let nombredeUsuario = 'Maria'; function mostrarMensaje() { let nombredeUsuario = "Bob"; // se declara una variable local let mensaje = 'Hola, ' + nombredeUsuario; // Bob alert(mensaje); } // la función creará y utilizará su propia variable nombredeUsuario mostrarMensaje(); alert( nombredeUsuario ); // Maria, sin cambios, la función no accedió a la variable externa
Variables globales
Las variables declaradas fuera de cualquier función, como la externa nombredeUsuario en el código anterior, se denominan globales .
Las variables globales son visibles desde cualquier función (a menos que estén sombreadas por los locales).
Por lo general, una función declara todas las variables específicas de su tarea. Las variables globales solo almacenan datos a nivel de proyecto, por lo que cuando es importante que estas variables sean accesibles desde cualquier lugar. El código moderno tiene pocos o ningún globo global. La mayoría de las variables residen en sus funciones.
Parámetros
Podemos pasar datos arbitrarios a funciones usando parámetros (también llamados argumentos de función ).
En el siguiente ejemplo, la función tiene dos parámetros: desde y text.
function mostrarMensaje(desde, texto) { // argumentos: desde, texto alert(desde+ ': ' + texto); } mostrarMensaje('Ann', 'Hola!'); // Ann: Hola! (*) mostrarMensaje('Ann', "¿Que pasa?"); // Ann: ¿Qué pasa? (**)
Cuando la función se llama en líneas (*)y (**), los valores dados se copian en las variables locales desde y text. Entonces la función los utiliza.
Aquí hay un ejemplo más: tenemos una variable desde y la pasamos a la función. Ten en cuenta: la función cambia desde, pero el cambio no se ve afuera, porque una función siempre obtiene una copia del valor:
function mostrarMensaje(desde, texto) { desde = '*' + desde+ '*'; // hacer que "desde" luzca mejor alert( desde+ ': ' + texto ); } let desde = "Ann"; mostrarMensaje(desde, "Hola"); // *Ann*: Hello // el valor de " desde " es el mismo, la función modificó una copia local alert( desde); // Ann
Valores predeterminados
Si no se proporciona un parámetro, entonces su valor se convierte undefined.
Por ejemplo, la función mencionada anteriormente mostrarMensaje(desde, texto)puede llamarse con un solo argumento:
mostrarMensaje("Ann");
Eso no es un error. Tal llamada saldría «Ann: undefined». No hay texto, así que se supone que texto === undefined.
Si queremos usar un «valor predeterminado» texto en este caso, podemos especificarlo después de = :
function mostrarMensaje(desde, texto = "no hay texto") { alert( desde + ": " + texto ); } mostrarMensaje("Ann"); // Ann: no hay texto Ahora, si el parámetro texto no se pasa, obtendrá el valor "no hay texto"
Aquí hay una cadena «no hay texto», pero puede ser una expresión más compleja, que solo se evalúa y asigna si falta el parámetro. Por lo tanto, esto también es posible:
function mostrarMensaje(desde, texto = otraFuncion()) { // otraFuncion() sólo se ejecuta si no se ha dado ningún texto // su resultado se convierte en el valor del texto }
Parámetros por defecto de estilo antiguo
Las ediciones antiguas de JavaScript no soportaban los parámetros por defecto. Así que hay formas alternativas de apoyarlos, que puede encontrar principalmente en los scripts antiguos.
Por ejemplo, una comprobación explícita de ser undefined:
function mostrarMensaje(desde, texto) { if (texto === undefined) { texto = 'no hay texto'; } alert( desde+ ": " + texto ); } ...O
El operador ||:
function mostrarMensaje(desde, texto) { // si el texto es falso, entonces el texto obtiene el valor "por defecto" text = text || 'no hay texto'; ... }
Devolviendo un valor
Una función puede devolver un valor al código de llamada como resultado.
El ejemplo más simple sería una función que suma dos valores:
function sum(a, b) { return a + b; } let result = sum(1, 2); alert( result ); // 3
La directiva return puede estar en cualquier lugar de la función. Cuando la ejecución lo alcanza, la función se detiene y el valor se devuelve al código de llamada (asignado a result anteriormente).
Puede haber muchas apariciones returnen una sola función. Por ejemplo:
function verificarEdad(edad) { if (edad> 18) { return true; } else { return confirm('¿Tienes permiso de los padres?'); } } let age = prompt('¿Qué edad tienes?', 18); if ( verificarEdad(edad) ) { alert( 'Acceso permitido' ); } else { alert( 'Acceso denegado' ); }
Es posible utilizar return sin un valor. Eso hace que la función salga inmediatamente.
Por ejemplo:
function verPelicula(edad) { if ( !verPelicula(edad) ) { return; } alert( "Mostrandote la pelicula" ); // (*) // ... }
En el código anterior, si verificarEdad(edad) se devuelve false, verPelicula no se procederá a la alert.
Una función con un vacío return o sin ella vuelve undefined.
Si una función no devuelve un valor, es lo mismo que si devuelve undefined:
function noHacerNada() { /* vacío*/ }
alert( noHacerNada() === undefined ); // true
Un return vacío también es lo mismo que return undefined:
function noHacerNada() { return; } alert( noHacerNada() === undefined ); // true
Nunca agregues una nueva línea entre return y el valor
Para una expresión larga return, podría ser tentador colocarlo en una línea separada, como esta:
return (alguna+ expresion + larga + o + lo + que + sea* f(a) + f(b))
Eso no funciona, porque JavaScript asume un punto y coma después return. Eso funcionará igual que:
return; (alguna + expresion + larga + o + lo + que + sea* f(a) + f(b))
Por lo tanto, efectivamente se convierte en un retorno vacío. Deberíamos poner el valor en la misma línea en su lugar.