Novedades ES6

Novedades ES6 - Funciones con parámetros por defecto

Las nuevas características de ES6, Javascript puede manejar valores por defecto en nuestras funciones de forma nativa. Además, podemos forzar a nuestras funciones a devolver una excepción en caso de que un argumento requerido falte.

La nueva característica de Javascript ES6 que te permite definir valores predeterminados para los parámetros de las funciones.
En la mayoría de los lenguajes de programación se permite definir valores predeterminados a los parámetros recibidos en las funciones, por lo que esta nueva característica de ES6 no sorprenderá seguramente a la mayoría de los lectores. No obstante es algo nuevo en las últimas versiones de Javascript, por lo que vamos a analizar con detalle esta característica del lenguaje.
Básicamente, los valores por defecto en los parámetros permiten asignar de manera predeterminada datos, que se asignan a los argumentos de la función, en caso que no se indique ningún valor en su invocación. Esos datos predeterminados se indican en la declaración de la función y resultan muy cómodos, a la vez que añaden versatilidad a las funciones de Javascript. Veremos a continuación ejemplos con los que aclarar posibles dudas y estudiar el detalle de este comportamiento.

Definir parámetros con valores por defecto en Javascript

Igual que en otros lenguajes, para definir los valores predeterminados de los parámetros, realizamos una asignación de esos valores a los parámetros en la cabecera de la función

function saludar(nombre = 'Miguel Angel') {
  return ('Hola ' + nombre);
}

Esta función recibe un parámetro llamado "nombre", con un valor predeterminado. Este valor se asignará en caso que al invocar a la función no le pasemos nada.

saludar();

Eso produciría la salida por consola "Hola Miguel Angel".
Pero, aunque indiquemos un valor predeterminado, podemos seguir invocando a la función enviando un valor diferente como parámetro.

saludar('DesarrolloWeb.com');

Justamente ésta es la versatilidad. La función sigue trabajando tal como lo conocíamos, agregando la posibilidad de tener un parámetro definido aunque no le pasemos nada.

<!DOCTYPE html>
<html>
<body>
<h2>Valores de parametros por Default</h2>
<script>
function saludar(nombre = 'Miguel Angel') {
  return ('Hola ' + nombre);
}
document.write(saludar()); // Hola Miguel Angel
document.write("<br>");
document.write(saludar('Daniel')); //Hola Daniel
</script>
</body>
</html>

El orden de los valores predeterminados a los parámetros importa

Los parámetros predeterminados en las funciones son muy fáciles de implementar, sin embargo tenemos que seguir unas pocas reglas. Básicamente, la más importante es la del orden de los parámetros en las llamadas a las funciones, que debe realizarse tal como está definido en la cabecera de la función. Esto es obvio, pero afecta directamente a los parámetros con valores por defecto en las funciones.
En resumen queremos hacer notar que, en una función donde unos argumentos tienen valores por defecto y otros no, debemos asegurarnos de colocar valores predeterminados en los últimos argumentos y no en los primeros. Creo que se ve mejor con un ejemplo.
Tenemos una función llamada "potencia" que calcula la potencia entre la base y el exponente. La base siempre la tenemos que indicar, pero sin embargo el exponente queremos que tenga un valor predeterminado. Si no indicamos nada, se entiende que el exponente será 2.

La función en cuestión es esta:

<!DOCTYPE html>
<html>
<body>
<h2>Valores de Parametros por Default</h2>
<script>

function potencia(base, exponente = 2) {
  let resultado = 1;
  for (let i = 0; i < exponente; i++) {
    resultado *= base;
  }
  return resultado;
}

document.write(potencia(3)); // indica 9 como resultado
document.write("<br>");
document.write(potencia(3,3)); // indica 27 como resultado
</script>

</body>
</html>


Fíjate que el parámetro que tiene valor por defecto es el último parámetro. Así te funcionará bien, puesto que si lo hiciéramos al revés no obtendríamos un resultado correcto. Observa ahora este código:
function potenciaMal(exponente = 2, base) {
  let resultado = 1;
  for (let i = 0; i < exponente; i++) {
    resultado *= base;
  }
  return resultado;
}

En este caso tenemos un problema por haber colocado valor predeterminado en el primer parámetro y en el segundo no. Se apreciará si enviamos un único parámetro a la función, donde obtendremos resultados quizás inesperados:

El orden de los valores predeterminados a los parámetros importa

Los parámetros predeterminados en las funciones son muy fáciles de implementar, sin embargo tenemos que seguir unas pocas reglas. Básicamente, la más importante es la del orden de los parámetros en las llamadas a las funciones, que debe realizarse tal como está definido en la cabecera de la función. Esto es obvio, pero afecta directamente a los parámetros con valores por defecto en las funciones.
En resumen queremos hacer notar que, en una función donde unos argumentos tienen valores por defecto y otros no, debemos asegurarnos de colocar valores predeterminados en los últimos argumentos y no en los primeros. Creo que se ve mejor con un ejemplo.
Tenemos una función llamada "potencia" que calcula la potencia entre la base y el exponente. La base siempre la tenemos que indicar, pero sin embargo el exponente queremos que tenga un valor predeterminado. Si no indicamos nada, se entiende que el exponente será 2.

La función en cuestión es esta:

function potencia(base, exponente = 2) {
  let resultado = 1;
  for (let i = 0; i < exponente; i++) {
    resultado *= base;
  }
  return resultado;
}
document.write(potencia(3)); // indica 9 como resultado
document.write(potencia(3, 3)); // indica 27 como resultado
Fíjate que el parámetro que tiene valor por defecto es el último parámetro. Así te funcionará bien, puesto que si lo hiciéramos al revés no obtendríamos un resultado correcto. Observa ahora este código:
function potenciaMal(exponente = 2, base) {
  let resultado = 1;
  for (let i = 0; i < exponente; i++) {
    resultado *= base;
  }
  return resultado;
}

En este caso tenemos un problema por haber colocado valor predeterminado en el primer parámetro y en el segundo no. Se apreciará si enviamos un único parámetro a la función, donde obtendremos resultados quizás inesperados:

console.log(potenciaMal(3)); // esto muestra NaN

El resultado ahora es "Not a Number" (NaN) porque el único valor indicado al invocar la función se asocia al primer parámetro (manda el orden de los parámetros en la declaración de la función, sin importar si existen o no valores predeterminados). El problema por tanto se nos da con el segundo argumento, que no tenía un valor predeterminado, y al no enviarlo en la invocación simplemente se queda indefinido. Al realizar los cálculos la función nos dice que el resultado no es un número (NaN).

Si aún no lo ves, puedes leer el código de esta función, que tiene el mismo problema.
function log(valor1 = 'Predeterminado', valor2) {
  console.log(valor1);
  console.log(valor2);
}

Si invocas la función enviando un solo parámetro, observarás el error:

log('algo'); // escribe 'algo' y luego 'undefined'

Usar variables para indicar los valores predeterminados

Algo interesante que podemos hacer para definir los valores predeterminados es usar variables. Por ejemplo:

let escuela = 'Academia';
function saludar(nombre = escuela) {
  console.log('Hola ' + nombre);
}

Ahora, si llamamos a saludar() sin enviar parámetros, dirá "Hola Academia".
Esto podría ser todavía más útil en un caso como el siguiente:

function potencia(base, exponente = base) {
  let resultado = 1;
  for (let i = 0; i < exponente; i++) {
    resultado *= base;
  }
  return resultado;
}
Como puedes observar, el valor por defecto indicado para el argumento "exponente" será el mismo valor que el indicado para "base". Así, indicada una base, se calculará la potencia cuyo exponente es la misma base.
console.log(potencia(1)); // muestra 1
console.log(potencia(2)); // muestra 4
console.log(potencia(3)); // muestra 27
console.log(potencia(4)); // muestra 256
console.log(potencia(4, 2)); // muestra 16
console.log(potencia(2, 1)); // muestra 2