Uso de parámetros predeterminados en ES6

Índice
  1. Parámetros predeterminados en ES5 y versiones anteriores
  2. Parámetros predeterminados en ES6
  3. Lidiar con los valores omitidos
  4. Valores de parámetros predeterminados y el argumentsobjeto
  5. Expresiones como parámetros predeterminados
  6. Conclusión

Recientemente comencé a investigar más sobre las novedades de JavaScript, poniéndome al día con muchas de las nuevas características y mejoras de sintaxis que se han incluido en ES6 (es decir, ES2015 y posteriores).

Probablemente hayas oído hablar de las cosas habituales y hayas comenzado a utilizarlas: funciones de flecha, operadores let y const, descanso y dispersión, etc. Sin embargo, una característica que me llamó la atención es el uso de parámetros predeterminados en funciones , que ahora es una característica oficial de ES6+. Esta es la capacidad de hacer que sus funciones iniciales tengan parámetros con valores predeterminados incluso si la llamada a la función no los incluye.

La característica en sí es bastante sencilla en su forma más simple, pero hay bastantes sutilezas y errores que querrás tener en cuenta, que intentaré aclarar en esta publicación con algunos ejemplos de código y demostraciones.

Parámetros predeterminados en ES5 y versiones anteriores

Una función que proporciona automáticamente valores predeterminados para parámetros no declarados puede ser una protección beneficiosa para sus programas, y esto no es nada nuevo.

Antes de ES6, es posible que hayas visto o usado un patrón como este:

function getInfo (name, year, color) {  year = (typeof year !== 'undefined') ? year : 2018;  color = (typeof color !== 'undefined') ? color : 'Blue';  // remainder of the function...}

En este caso, la getInfo()función tiene solo un parámetro obligatorio: name. Los parámetros yearson coloropcionales, por lo que si no se proporcionan como argumentos cuando getInfo()se llama a , se les asignarán valores predeterminados:

getInfo('Chevy', 1957, 'Green');getInfo('Benz', 1965); // default for color is "Blue"getInfo('Honda'); // defaults are 2018 and "Blue"

Pruébelo en CodePen

Sin este tipo de control y protección, cualquier parámetro no iniciado tendría por defecto un valor de undefined, lo que normalmente no es deseable.

También puedes usar un patrón verdadero/falso para verificar parámetros que no tienen valores:

function getInfo (name, year, color) {  year = year || 2018;  color = color || 'Blue';  // remainder of the function...}

Pero esto puede causar problemas en algunos casos. En el ejemplo anterior, si pasa un valor de 0para el año, el valor predeterminado 2018 lo anulará porque 0se evalúa como falso. En este ejemplo específico, es poco probable que le preocupe eso, pero hay muchos casos en los que su aplicación podría querer aceptar un valor de 0 como un número válido en lugar de un valor falso.

Pruébelo en CodePen

Por supuesto, incluso con el typeofpatrón, es posible que tengas que hacer más comprobaciones para tener una solución verdaderamente a prueba de balas. Por ejemplo, es posible que espere una función de devolución de llamada opcional como parámetro. En ese caso, compararlo undefinedsolo no sería suficiente. También deberías comprobar si el valor pasado es una función válida.

Esto es un pequeño resumen que cubre cómo manejamos los parámetros predeterminados antes de ES6. Vemos una manera mucho mejor.

Parámetros predeterminados en ES6

Si su aplicación requiere que utilice funciones anteriores a ES6 por motivos heredados o debido a la compatibilidad del navegador, es posible que deba hacer algo similar a lo que describí anteriormente. Pero ES6 lo ha hecho mucho más fácil. A continuación se explica cómo definir valores de parámetros predeterminados en ES6 y más allá:

function getInfo (name, year = 2018, color = 'blue') {  // function body here...}

Pruébelo en CodePen

Es así de simple.

Si se pasan valores yeary colora la llamada de función, los valores pasados ​​como argumentos reemplazarán a los definidos como parámetros en la definición de la función. Esto funciona exactamente de la misma manera que con los patrones de ES5, pero sin ese código adicional. Mucho más fácil de mantener y mucho más fácil de leer.

Esta característica se puede utilizar para cualquiera de los parámetros en el encabezado de la función, por lo que podría establecer un valor predeterminado para el primer parámetro junto con otros dos valores esperados que no tienen valores predeterminados:

function getInfo (name = 'Pat', year, color) {  // function body here...}

Lidiar con los valores omitidos

Tenga en cuenta que, en un caso como el anterior, si desea omitir el nameargumento opcional (y, por lo tanto, usar el valor predeterminado) mientras incluye un yearand color, deberá pasarlo undefinedcomo marcador de posición para el primer argumento:

getInfo(undefined, 1995, 'Orange');

Si no hace esto, lógicamente siempre se asumirá que el primer valor es name.

Lo mismo se aplicaría si quisieras omitir el yearargumento (el segundo) e incluir los otros dos (asumiendo, por supuesto, que el segundo parámetro es opcional):

getInfo('Charlie', undefined, 'Pink');

También debes tener en cuenta que lo siguiente puede producir resultados inesperados:

function getInfo (name, year = 1965, color = 'blue') {  console.log(year); // null}getInfo('Frankie', null, 'Purple');

Pruébelo en CodePen

En este caso, pasé el segundo argumento como null, lo que podría llevar a algunos a creer que el yearvalor dentro de la función debería ser 1965, que es el valor predeterminado. Pero esto no sucede porque nullse considera un valor válido. Y esto tiene sentido porque, según la especificación, nullel motor JavaScript lo ve como la ausencia intencional del valor de un objeto, mientras que undefinedse ve como algo que sucede incidentalmente (por ejemplo, cuando una función no tiene un valor de retorno, devuelve undefined). .

Así que asegúrese de usarlo undefinedy no nullcuando desee que se use el valor predeterminado. Por supuesto, puede haber casos en los que desee utilizar nully luego tratar el nullvalor dentro del cuerpo de la función, pero debe estar familiarizado con esta distinción.

Valores de parámetros predeterminados y el argumentsobjeto

Otro punto que vale la pena mencionar aquí es el relacionado con el argumentsobjeto. El argumentsobjeto es un objeto similar a una matriz, accesible dentro del cuerpo de una función, que representa los argumentos pasados ​​a una función.

De modo no estricto, el argumentsobjeto refleja cualquier cambio realizado en los valores de los argumentos dentro del cuerpo de la función. Por ejemplo:

function getInfo (name, year, color) {  console.log(arguments);  /*  [object Arguments] {    0: "Frankie",    1: 1987,    2: "Red"  }  */    name = 'Jimmie';  year = 1995;  color = 'Orange';  console.log(arguments);  /*  [object Arguments] {    0: "Jimmie",    1: 1995,    2: "Orange"  }  */}getInfo('Frankie', 1987, 'Red');

Pruébelo en CodePen

Observe que, en el ejemplo anterior, si cambian los valores de los parámetros de la función, esos cambios se reflejan en el argumentsobjeto. Esta característica se demostró más problemática que beneficiosa, por lo que en el modo estricto el comportamiento es diferente:

function getInfo (name, year, color) {  'use strict';  name = 'Jimmie';  year = 1995;  color = 'Orange';  console.log(arguments);  /*  [object Arguments] {    0: "Frankie",    1: 1987,    2: "Red"  }  */}  getInfo('Frankie', 1987, 'Red');

Pruébelo en CodePen

Como se muestra en la demostración, en modo estricto el argumentsobjeto conserva sus valores originales para los parámetros.

Eso nos lleva al uso de parámetros predeterminados. ¿Cómo se comporta el argumentsobjeto cuando se utiliza la función de parámetros predeterminados? Echa un vistazo al siguiente código:

function getInfo (name, year = 1992, color = 'Blue') {  console.log(arguments.length); // 1    console.log(year, color);  // 1992  // "Blue"  year = 1995;  color = 'Orange';  console.log(arguments.length); // Still 1  console.log(arguments);  /*  [object Arguments] {    0: "Frankie"  }  */    console.log(year, color);  // 1995  // "Orange"}getInfo('Frankie');

Pruébelo en CodePen

Hay algunas cosas a tener en cuenta en este ejemplo.

Primero, la inclusión de parámetros predeterminados no cambia el argumentsobjeto. Entonces, como en este caso, si paso solo un argumento en la llamada funcional, el argumentsobjeto contendrá un solo elemento, incluso con los parámetros predeterminados presentes para los argumentos opcionales.

En segundo lugar, cuando los parámetros predeterminados están presentes, el argumentsobjeto siempre se comportará de la misma manera en modo estricto y en modo no estricto. El ejemplo anterior está en modo no estricto, que generalmente permite argumentsmodificar el objeto. Pero esto no sucede. Como puede ver, la longitud de argumentssigue siendo la misma después de modificar los valores. Además, cuando se registra el objeto en sí, el namevalor es el único presente.

Expresiones como parámetros predeterminados

La función de parámetros predeterminados no se limita a valores estáticos, sino que puede incluir una expresión que se evaluará para determinar el valor predeterminado. A continuación se muestra un ejemplo para demostrar algunas cosas que son posibles:

function getAmount() {  return 100;}function getInfo (name, amount = getAmount(), color = name) {  console.log(name, amount, color)}getInfo('Scarlet');// "Scarlet"// 100// "Scarlet"getInfo('Scarlet', 200);// "Scarlet"// 200// "Scarlet"getInfo('Scarlet', 200, 'Pink');// "Scarlet"// 200// "Pink"

Pruébelo en CodePen

Hay algunas cosas a tener en cuenta en el código anterior. Primero, estoy permitiendo que el segundo parámetro, cuando no está incluido en la llamada a la función, sea evaluado por medio de la getAmount()función. Esta función se llamará solo si no se pasa un segundo argumento. Esto es evidente en la segunda getInfo()llamada y el registro posterior.

El siguiente punto clave es que puedo usar un parámetro anterior como predeterminado para otro parámetro. No estoy del todo seguro de qué tan útil sería esto, pero es bueno saber que es posible. Como se puede ver en el código anterior, la getInfo()función establece el tercer parámetro ( color) para que sea igual al valor del primer parámetro ( name), si el tercer parámetro no está incluido.

Y, por supuesto, dado que es posible utilizar funciones para determinar los parámetros predeterminados, también puede pasar un parámetro existente a una función utilizada como parámetro posterior, como en el siguiente ejemplo:

function getFullPrice(price) {  return (price * 1.13);}function getValue (price, pricePlusTax = getFullPrice(price)) {  console.log(price.toFixed(2), pricePlusTax.toFixed(2))}getValue(25);// "25.00"// "28.25"getValue(25, 30);// "25.00"// "30.00"

Pruébelo en CodePen

En el ejemplo anterior, estoy haciendo un cálculo de impuestos rudimentario en la getFullPrice()función. Cuando se llama a esta función, utiliza el priceparámetro existente como parte de la pricePlusTaxevaluación. Como se mencionó anteriormente, la getFullPrice()función no se llama si se pasa un segundo argumento getValue()(como se demostró en la segunda getValue()llamada).

Dos cosas a tener en cuenta respecto a lo anterior. Primero, la llamada a la función en la expresión del parámetro predeterminado debe incluir paréntesis; de lo contrario, recibirá una referencia a la función en lugar de una evaluación de la llamada a la función.

En segundo lugar, solo puede hacer referencia a parámetros anteriores con parámetros predeterminados. En otras palabras, no puedes hacer referencia al segundo parámetro como argumento en una función para determinar el valor predeterminado del primer parámetro:

// this won't workfunction getValue (pricePlusTax = getFullPrice(price), price) {  console.log(price.toFixed(2), pricePlusTax.toFixed(2))}getValue(25); // throws an error

Pruébelo en CodePen

De manera similar, como era de esperar, no puede acceder a una variable definida dentro del cuerpo de la función desde un parámetro de función.

Conclusión

Esto debería cubrir casi todo lo que necesita saber para aprovechar al máximo el uso de parámetros predeterminados en sus funciones en ES6 y superiores. La función en sí es bastante fácil de usar en su forma más simple pero, como comenta aquí, hay bastantes detalles que vale la pena comprender.

Si deseas leer más sobre este tema, aquí hay algunas fuentes:

  • Comprensión de ECMAScript 6 por Nicholas Zakas. Esta fue mi fuente principal para este artículo. Nicolás es definitivamente mi autor de JavaScript favorito.
  • Objeto de argumentos en MDN
  • Parámetros predeterminados en MDN
SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion