Repensando JavaScript: Death of the For Loop

El for loop JavaScript nos ha servido bien, pero ahora está obsoleto y debería retirarse a favor de nuevas técnicas de programación funcional.

Afortunadamente, este es un cambio que no requiere que seas un maestro de programación funcional. ¡Aún mejor, esto es algo que puedes hacer hoy en proyectos existentes!

¿Cuál es el problema con el bucle de JavaScript para todos modos?

El diseño del for loop fomenta la mutación del estado y el uso de los efectos secundarios , que son posibles fuentes de código erróneo e impredecible.

Todos hemos escuchado que el estado global es malo y debe evitarse. Sin embargo, el estado local comparte los mismos males que el estado global , simplemente no lo notamos tan a menudo porque es en una escala más pequeña. Entonces nunca resolvimos el problema, simplemente lo minimizamos.

Con un estado mutable, en algún punto desconocido en el tiempo, una variable cambiará por un motivo desconocido y pasarás horas depurando y buscando el motivo por el que cambió el valor. Ya me he sacado una docena de pelos de la cabeza solo de pensar en esto.

A continuación, me gustaría hablar rápidamente sobre los efectos secundarios . Esas palabras suenan terribles, efectos secundarios. Yuck. ¿Quieres que tu programa tenga efectos secundarios? No, no quiero que mis programas tengan efectos secundarios.

Pero, ¿qué es un efecto secundario?

Se considera que una función tiene efectos secundarios cuando modifica algo fuera del alcance de la función . Podría estar cambiando el valor de una variable, leyendo la entrada del teclado, realizando una llamada de API, escribiendo datos en el disco, iniciando sesión en una consola, etc.

Los efectos secundarios son poderosos, pero con gran poder viene una gran responsabilidad.

Los efectos secundarios deben eliminarse cuando sea posible o encapsulados y administrados. Las funciones con efectos secundarios son más difíciles de probar y más difíciles de razonar , así que sáquelas cada vez que pueda. Afortunadamente, no vamos a preocuparnos por los efectos secundarios aquí.

De acuerdo, menos palabras más código. Echemos un vistazo a un for loop típico que probablemente haya visto miles de veces.

 const cats = [ 
{nombre: 'Mojo', meses: 84},
{nombre: 'Mao-Mao', meses: 34},
{nombre: 'Waffles', meses: 4},
{nombre: 'Pickles', meses: 6}
]
 var gatitos = [] 
 // típico mal escrito `for loop` 
para (var i = 0; i <cats.length; i ++) {
if (gatos [i] .months <7) {
gatitos.push (gatos [i] .name)
}
}
 console.log (gatitos) 

Mi plan es refactorizar este código paso a paso para que pueda ver lo fácil que es transformar su propio código en algo más hermoso.

El primer cambio que quiero hacer es extraer la sentencia if en su propia función.

 const isKitten = cat => cat.months <7 
 var gatitos = [] 
 para (var i = 0; i <cats.length; i ++) { 
if ( isKitten (cats [i]) ) {
gatitos.push (gatos [i] .name)
}
}

En general, es una buena práctica extraer sus declaraciones if . El cambio en el filtrado de "menos de 7 meses" a "es un gatito" es un gran problema. Ahora cuando lees el código, la intención se vuelve clara. ¿Por qué recibimos gatos de menos de 7 meses? Esto no está claro en absoluto. Nuestra intención es encontrar gatitos, ¡así que deja que el código diga eso!

Otro beneficio es isKitten ahora es reutilizable y todos sabemos,

hacer que nuestro código sea reutilizable siempre debe ser uno de nuestros objetivos.

El siguiente cambio es extraer la transformación (o mapeo) de un objeto de tipo cat a un nombre. Este cambio tendrá más sentido más adelante, así que por ahora solo tendrás que confiar en mí.

 const isKitten = cat => cat.months <7 
const getName = cat => cat.name
 var gatitos = [] 
 para (var i = 0; i <cats.length; i ++) { 
if (isKitten (cats [i])) {
gatitos.push ( getName (gatos [i]) )
}
}

Consideré escribir algunos párrafos para describir la mecánica del filter y el map . Pero creo que al no describirlos y, en su lugar, mostrarle cuán fácilmente puede leer y comprender este código, incluso sin haber sido introducido en el map o filter , lo mejor sería demostrar qué tan legible puede ser su código.

 const isKitten = cat => cat.months <7 
const getName = cat => cat.name
 const gatitos = 
cats.filter (isKitten)
.map (getName)

También note que hemos eliminado kittens.push(...) . ¡No más mutación de estado y no más var !

El código que usa const (sobre var y let) es sexy como el infierno

La revelación completa aquí, podríamos haber usado const todo el tiempo porque const no hace que el objeto sea inmutable (más sobre esto en otro momento). Pero bueno, es un ejemplo artificial, ¡así que no me molestes!

La última refactorización que sugeriría es extraer también el filtrado y el mapeo a su propia función (ya sabes, para todo eso de la reutilización).

Y todos juntos ahora:

 const isKitten = cat => cat.months <7 
const getName = cat => cat.name
const getKittenNames = cats =>
cats.filter (isKitten)
.map (getName)
 const cats = [ 
{nombre: 'Mojo', meses: 84},
{nombre: 'Mao-Mao', meses: 34},
{nombre: 'Waffles', meses: 4},
{nombre: 'Pickles', meses: 6}
]
 const gatitos = getKittenNames (gatos) 
 console.log (gatitos) 

Crédito adicional

Para obtener más crédito, tómalo más lejos. Desacopla los métodos de filter y map de sus objetos. Y doble crédito extra podría investigar la composición de la función.

JavaScript funcional: métodos de desacoplamiento de sus objetos
Una cosa que siempre termino haciendo en mi proyecto es desacoplar métodos de sus objetos. mapa, filtro y reducir no son … hackernoon.com
JavaScript funcional: composición de funciones para uso diario.
La composición de funciones tiene que ser mi parte favorita de la programación funcional. Espero brindarte un buen real … hackernoon.com

¿Qué hay de descanso?

Muchos de ustedes preguntaron: "¿Qué hay de los descansos?" Echa un vistazo a la Parte 2: El descanso es el GOTO de los bucles. (sugerencia: recursividad)

Repensando JavaScript: Break es el GOTO de bucles
En mi último artículo, Death of the for Loop, intenté convencerte de que abandonaras el bucle for por un más funcional … medium.com

Fin

Por favor, hágame saber cómo se siente al respecto en los comentarios a continuación. ¿El for loop ahora también está muerto para ti?

Sé que es algo pequeño, pero me alegra el día cuando recibo las siguientes notificaciones en Medium y Twitter ( @joelnet ). O si crees que estoy lleno de mierda, dime en los comentarios a continuación.

¡Aclamaciones!

Artículos relacionados

Repensando JavaScript: la declaración if
Pensar funcionalmente me ha abierto la mente sobre la programación. medium.com
Repensando JavaScript: elimine la declaración de cambio para un mejor código
En mis últimos 3 artículos, lo convencí de que elimine la sentencia if, elimine el bucle for y nunca use break. medium.com
JavaScript funcional: resolución de promesas secuencialmente
Me encanta la nueva biblioteca Promise que se incluye con ES6, aunque una cosa se ha omitido , una función secuencial … medium.com

Este artículo ha sido traducido al ruso para mis amigos rusos.

Hacker Noon es cómo los hackers comienzan sus tardes. Somos parte de la familia @AMI . Ahora estamos aceptando presentaciones y estamos felices de conversar sobre oportunidades de publicidad y patrocinio .

Si disfrutaste esta historia, te recomendamos que leas nuestras últimas historias tecnológicas e historias tecnológicas de tendencia . Hasta la próxima, ¡no des por sentado las realidades del mundo!