Parámetros y return
En resumen: Un parámetro es una variable de la función que recibe el valor pasado en la llamada (el argumento), y return devuelve un resultado a quien hace la llamada.
Problema
Un recibo, totales distintos
Quieres una función que imprima la última línea del recibo: «Total: … €». Pero el total es distinto en cada pedido.
Las funciones de la lección anterior imprimen siempre lo mismo. Una función printTotal() no tiene de dónde saber el total. Tampoco quieres una función aparte para cada total. Necesitas una forma de pasar el total a la función cuando la llamas.
La idea
Parámetros: lo que recibe la función
Entre paréntesis escribes un nombre para lo que la función espera. Eso es un parámetro. Dentro de la función es una variable normal.
Al hacer la llamada, pones el valor entre paréntesis. Ese valor se llama argumento.
function printTotal(total) { console.log(`Total: ${total} €`);}
printTotal(12.5);printTotal(4.2);Total: 12.5 €Total: 4.2 €total es el parámetro. 12.5 y 4.2 son los argumentos. Hay una sola función, y imprime totales distintos.
Delante del parámetro no se escribe un tipo: JavaScript no comprueba lo que pasas. Si pasas un texto en lugar de un número, la función lo imprime sin quejarse. Por eso el nombre del parámetro tiene que decir con claridad qué se espera.
Si hay varios parámetros, los separas con comas. Los argumentos se pasan en el mismo orden.
Pruébalo
Por posición, no por nombre
¿Qué imprimirá el programa?
function printLine(item, qty) { console.log(`${item}: ${qty} uds.`);}
const coffee = "Café";const qty = 3;printLine(coffee, 2);Los argumentos se asocian con los parámetros por posición: el primero con item, el segundo con qty. La variable qty de fuera no tiene nada que ver con el parámetro qty, aunque se llamen igual.
Problema
¿Por qué no bajó el precio?
Has escrito una función para un descuento del 10% y la has llamado:
function applyDiscount(price) { price = price * 0.9;}
const price = 100;applyDiscount(price);console.log(price); // 100100El precio sigue siendo 100. La función no da ningún error, y aun así el descuento no está. ¿Adónde fue?
Míralo
La función recibe una copia
function applyDiscount(price) { price = price * 0.9;}
const price = 100;applyDiscount(price);console.log(price); // 100Paso a paso, en palabras
- En el programa hay una variable price = 100.
- Llamas a applyDiscount(price): se reserva memoria nueva para la función.
- El valor se copia en su parámetro price.
- La función rebaja su copia: 100 * 0.9 = 90.
- La función termina y su memoria desaparece, junto con la copia.
- Y price en el programa sigue siendo 100.
Al llamarla, la función no recibe la variable price en sí, sino una copia de su valor. Rebaja la copia. Cuando la función termina, su memoria desaparece, y la copia con ella. Esto se llama paso por valor.
Las dos variables se llaman igual (price) a propósito: es justo lo que confunde en la práctica. El nombre no importa. Cada función tiene sus propias variables.
Más precisamente, para curiosos
En JavaScript, los argumentos siempre se pasan por valor. Con los arrays y los objetos, lo que se copia es el enlace a ellos, así que los cambios hechos dentro de la función se ven también fuera:
function addItem(items) { items.push("leche");}
const cart = ["pan"];addItem(cart);console.log(cart);[ 'pan', 'leche' ]Veremos los objetos en el módulo «Clases y objetos».
La idea
return: la función devuelve un resultado
La solución es que la función devuelva el nuevo precio. En el cuerpo escribes return y el valor. El tipo del resultado no se escribe: function es igual tanto si la función devuelve algo como si no.
function applyDiscount(price) { return price * 0.9;}
let price = 100;price = applyDiscount(price);console.log(price); // 90Paso a paso, en palabras
- En el programa: price = 100.
- Llamas a applyDiscount(price): se reserva memoria para la función.
- El valor se copia en el parámetro price.
- return price * 0.9: el resultado es 90.
- El resultado vuelve al programa y se guarda en price.
- Ahora price en el programa es 90.
La llamada applyDiscount(price) ahora es un valor. Puedes guardarlo en una variable (como aquí), imprimirlo o hacer cálculos con él.
Más precisamente, para curiosos
- Una función sin
returntambién devuelve algo:undefined, el valor «nada». Si imprimes el resultado de la primera versión, que solo rebajaba su propia copia, eso es justo lo que ves:
function applyDiscount(price) { price = price * 0.9;}
console.log(applyDiscount(100));undefined- También puedes escribir
returnsin valor. Simplemente termina la función.
- Una función puede devolver varios valores a la vez en un array, y en la llamada los repartes en variables separadas con los corchetes
[ ]:
function getLimits() { return [1, 10];}
const [low, high] = getLimits();console.log(low, high);1 10Pruébalo
¿Cuál es el resultado?
La función calcula un IVA del 20% sobre el precio. ¿Qué tiene que ir en el hueco para que quien la llama reciba el resultado?
function vat(price) {
price * 0.2;
}return: sin él, la función calcula price * 0.2 y tira el resultado, y la llamada da undefined.Pruébalo
Devuelto, pero perdido
¿Qué imprimirá el programa?
function reserve(seats) { seats = seats - 2; console.log(`dentro: ${seats}`); return seats;}
const seats = 10;reserve(seats);console.log(`fuera: ${seats}`);La función cambia su copia y devuelve 8, pero nadie guarda el resultado. Para conservarlo, necesitas seats = reserve(seats);.
Entonces seats tiene que declararse con let, porque su valor cambia.
La idea
return termina la función
La tienda no cobra el envío en los pedidos de 50 € o más. Si no, el envío cuesta 4,99 €:
function shippingCost(total) { if (total >= 50) { return 0; } return 4.99;}
console.log(shippingCost(62.0));console.log(shippingCost(18.5));04.99En cuanto llega a return, la función termina en ese momento. Por eso, con 62 €, el segundo return no se ejecuta, y no necesitamos un else.
Una función con resultado tiene que devolver un valor en cada camino. Pero JavaScript no lo comprueba. Si quitas la última línea, el programa se ejecuta, y para un pedido de 18,50 € la función llega a su final sin un return y devuelve undefined:
function shippingCost(total) { if (total >= 50) { return 0; }}
console.log(shippingCost(62.0));console.log(shippingCost(18.5));0undefinedNo hay error, así que un descuido así cuesta de detectar. Fíjate en la salida y prueba cada camino de la función.
Pruébalo
Encuentra el error
Los socios del club tienen un 10% de descuento, y los demás pagan el precio completo. Pero todos reciben el descuento. ¿En qué línea está el error?
Elige la línea con el error.
El último return es para quienes no son socios: pagan el precio completo, return price;.
Ejercicio
Funciones que calculan
Resuelve las tareas en tu editor. Cada función recibe lo que necesita como parámetros y devuelve el resultado. La impresión se hace fuera de las funciones, en las líneas de debajo.
1. Media aritmética. La función average(values) devuelve la media de los números del array. Debajo, lee del teclado cuántos números hay y después los números.
51015202530Media: 202. Número primo. La función isPrime(n) devuelve si el número es primo (divisible solo por 1 y por sí mismo). Para 7 devuelve true, para 12 false.
3. Temperaturas. Las funciones toFahrenheit(c) y toCelsius(f). F = C · 9 / 5 + 32. Lee una temperatura y una unidad (C o F) e imprime la temperatura convertida.
100C100 C = 212 F4. Calculadora. La función calculate(a, b, op) devuelve el resultado para +, -, * o /. La operación se elige con if.
105+10 + 5 = 155. Un triángulo con parámetro. Lo prometimos en la lección anterior. La función printTriangle(height) imprime un triángulo rectángulo de asteriscos con altura height. Para 3:
** ** * *Más precisamente, para curiosos
En JavaScript, / siempre da un número decimal, así que 5 / 9 es 0.5555…, no 0 como en Java y C#. Si necesitas la parte entera, escribe Math.trunc(a / b):
console.log(5 / 9);console.log(Math.trunc(7 / 2));0.55555555555555563Ejercicio
Funciones para arrays
Cada tarea es una función que recibe un array (o una palabra) y devuelve un resultado. Al final, júntalas todas en un programa.
sum,sumEvenysumOdd: la suma de todos los números, de los pares y de los impares del array.reverse: devuelve un array nuevo con los números en orden inverso.maxymin: el número mayor y el menor.isPalindrome(word): si la palabra se lee igual de izquierda a derecha que de derecha a izquierda.sumDiagonalsysumDiagonalsOnce: la suma de las dos diagonales de una matriz cuadrada, contando el elemento central dos veces y una vez.- Todo junto: para el array
[1, 2, 3, 4, 5], el número 7 (conisPrimede la tarjeta anterior), las palabras «radar» y «ABCDE» y la matriz de 3 × 3 con los números del 1 al 9.
Suma: 15, Pares: 6, Impares: 9Invertido: [5, 4, 3, 2, 1]Máx: 5, Mín: 17 es primo: trueradar: true, ABCDE: falseSuma con repetición: 30, Suma sin repetición: 25Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: Bucles · Arrays · Arrays bidimensionales · Funciones
- Continúa en: Valores por defecto · Recursión · Clases y objetos · Constructores y this
- Ejercicios sobre el tema: Funciones