5 consejos para escribir funciones de flecha de calidad

Las funciones de flecha de JavaScript son bastante populares. Y se lo merecen, ya que difieren en la sintaxis lacónica, la unión léxica thisy el hecho de que son muy convenientes para usar como devoluciones de llamada. El material, cuya traducción publicamos hoy, incluye 5 recomendaciones sobre el uso de las funciones de flecha. Quien aprovecha estas recomendaciones tiene la oportunidad de revelar más plenamente el potencial de tales funciones.





1. Use la visualización de los nombres de las funciones de flecha


Las funciones de flecha de JavaScript son anónimas: su propiedad namecontiene una cadena vacía - ''.

( number => number + 1 ).name; // => ''

Las funciones anónimas se marcan como anonymousdurante la depuración o al analizar la pila de llamadas. Desafortunadamente, la palabra anonymousno contiene una pista sobre a qué código específico se relaciona.

Este es uno de los puntos en el código de depuración donde se llaman funciones anónimas.


Código de depuración que contiene funciones anónimas

La pila de llamadas en el lado derecho de la figura contiene referencias a 2 funciones marcadas comoanonymous. A partir de dicha información contenida en la pila de llamadas, uno no puede aprender nada útil sobre el código.

Afortunadamente, JavaScript tiene un mecanismo para derivar nombres de funciones (función ES2015), que es capaz, bajo ciertas condiciones, de detectar un nombre de función. La idea de mostrar el nombre es que JavaScript puede averiguar el nombre de la función de flecha desde su posición sintáctica, es decir, en función del nombre de la variable que almacena el enlace al objeto de la función.

Veamos el mecanismo para derivar nombres de funciones en acción:

const increaseNumber = number => number + 1;

increaseNumber.name; // => 'increaseNumber'

Dado que la referencia a la función de flecha se almacena en una variable increaseNumber, JavaScript decide que el nombre es 'increaseNumber'adecuado para la función. Como resultado, la función de flecha también recibe ese nombre.

Se recomienda utilizar el mecanismo de derivación del nombre de la función para nombrar las funciones de flecha.

Ahora veamos el proceso de depuración, durante el cual se utiliza el mecanismo para derivar nombres de funciones.


Depuración de código que contiene funciones de flecha que tienen nombres

Dado que las funciones de flecha ahora tienen nombres, la pila de llamadas proporciona más información útil sobre el código que se está ejecutando:

  • El nombre de la función handleButtonClickindica una llamada al controlador de eventos click.
  • El nombre increaseCounterindica una llamada a la función que incrementa el contador.

2. Siempre que sea posible, esforzarse por escribir funciones en línea


Una función "en línea" es una función que consiste en una sola expresión. En las funciones de flecha, me gusta el hecho de que son muy convenientes de usar para crear funciones cortas en línea.

Por ejemplo, aquí está la forma "completa" de una función de flecha:

const array = [1, 2, 3];

array.map((number) => { 
  return number * 2;
});

Esta característica se puede hacer fácilmente más compacta. Es decir, dado que la función contiene solo una expresión, puede eliminar llaves y return:

const array = [1, 2, 3];

array.map(number => number * 2);

Se recomienda que si una función contiene solo una expresión, que esté en línea.

3. Utilice con cuidado las funciones de flecha y los operadores de comparación.


Los operadores de comparación >, <, <=y >=son muy similares a la flecha =>por que declaran flecha funciones (tales flechas también se llama "una flecha en negrita").

Cuando se utilizan operadores de comparación en una función en línea, el código resultante puede no ser muy claro.

Declare una función de flecha que usa el operador <=:

const negativeToZero = number => number <= 0 ? 0 : number;

La presencia en una línea de caracteres =>y <=desorienta al lector de código.

Para distinguir claramente las flechas de los operadores de comparación, se pueden utilizar varios enfoques.

Primero, puede encerrar la expresión entre paréntesis:

const negativeToZero = number => (number <= 0 ? 0 : number);

En segundo lugar, puede declarar intencionalmente una función de flecha usando una construcción más larga:

const negativeToZero = number => {
  return number <= 0 ? 0 : number;
};

Estas transformaciones eliminan la incertidumbre causada por el uso del símbolo de flecha y los operadores de comparación en una línea.

Se recomienda que si la función de una sola línea de una flecha contiene declaraciones >, <, <=y >=, para concluir la expresión correspondiente entre paréntesis o utilizar un multi-forma de anuncios flecha funciones.

4. Use paréntesis o estructuras de líneas múltiples al crear objetos simples en funciones de flecha


El uso de un objeto literal dentro de una función de flecha incrustada dará como resultado un error de sintaxis:

const array = [1, 2, 3];

//  SyntaxError!
array.map(number => { 'number': number });

JavaScript considera que las llaves son un bloque de código, no un objeto literal.

Si encierra el objeto literal entre paréntesis, este problema se resolverá:

const array = [1, 2, 3];

// !
array.map(number => ({ 'number': number }));

Si un objeto literal tiene muchas propiedades, entonces aquí puede incluso usar saltos de línea. La función de flecha aún permanece incrustada:

const array = [1, 2, 3];

// !
array.map(number => ({
  'number': number
  'propA': 'value A',
  'propB': 'value B'
}));

Los literales de objetos, cuando se usan en funciones en línea, se recomiendan entre paréntesis.

5. Tenga cuidado de anidar demasiado profundamente.


Las funciones de flecha difieren en la sintaxis lacónica. Es bueno. Pero debido a esto, muchas funciones de flecha incrustadas entre sí pueden formar estructuras difíciles de leer.

Considere el siguiente escenario. Cuando hacen clic en el botón, se ejecuta una solicitud al servidor. Cuando se recibe una respuesta del servidor que contiene un conjunto de ciertos elementos, los nombres de estos elementos se muestran en la consola:

myButton.addEventListener('click', () => {
  fetch('/items.json')
    .then(response => response.json())
    .then(json => {
      json.forEach(item => {
        console.log(item.name);
      });
    });
});

Aquí vemos tres niveles de funciones de flecha de anidación. Para profundizar en lo que está sucediendo en este código, debe pasar un tiempo.

Se pueden usar varios enfoques para mejorar la legibilidad de las funciones anidadas.

El primer enfoque es escribir referencias de funciones a variables. Los nombres de las variables deben describir brevemente la esencia de la función (eche un vistazo a la recomendación n. ° 1 sobre la derivación de los nombres de las funciones).

const readItemsJson = json => {
  json.forEach(item => console.log(item.name));
};

const handleButtonClick = () => {
  fetch('/items.json')
    .then(response => response.json());
    .then(readItemsJson);
};

myButton.addEventListener('click', handleButtonClick);

Durante la refactorización, extrajimos las funciones de flecha anidadas y las escribimos en las variables readItemsJsony handleButtonClick. El nivel de anidación del código disminuyó de 3 a 2. Ahora el código se ha vuelto más comprensible.

Otra opción para refactorizar este código es traducir toda la función a un formato async/await. Esta es una excelente manera de resolver el problema de las funciones anidadas:

const handleButtonClick = async () => {
  const response = await fetch('/items.json');
  const json = await response.json();
  json.forEach(item => console.log(item.name));
};

myButton.addEventListener('click', handleButtonClick);

Se recomienda evitar niveles de anidamiento demasiado profundos de las funciones de flecha, extrayéndolos en variables como funciones separadas o, si es posible, utilizando la sintaxis async/await.

Resumen


Las funciones de flecha de JavaScript son anónimas. Para que la depuración de código sea más productiva, se recomienda utilizar variables que almacenen referencias de funciones. Esto permite que JavaScript muestre nombres de funciones.

Las funciones de flecha incorporadas son útiles cuando el cuerpo de la función contiene solo una expresión.

Operadores >, <, <=y >=como una flecha =>que se utiliza cuando se declaran los interruptores de función. Cuando estos operadores se usan en el cuerpo de una función de flecha incorporable, debe considerar la conversión de código.

La sintaxis de los literales de objetos, como { prop: 'value' }, es como un bloque de código {}. Como resultado, cuando un objeto literal se coloca dentro de una función de flecha incrustada, debe encerrarse entre paréntesis:() => ({ prop: 'value' }).

Los niveles demasiado altos de anidamiento de funciones confunden a quien lee el código. Se recomienda reducir el nivel de anidación de funciones extrayéndolas y escribiéndolas en variables. Otro enfoque para reducir el nivel de anidación de código es utilizar una construcción async/await.

¡Queridos lectores! ¿Conoces algún truco interesante para usar las funciones de flecha?

Source: https://habr.com/ru/post/undefined/


All Articles