Rethinking JavaScript: Death of the For Loop

O JavaScript for loop nos serviu bem, mas agora é obsoleto e deve ser aposentado em favor de novas técnicas de programação funcional.

Felizmente, esta é uma mudança que não exige que você seja um mestre de programação funcional. Ainda melhor, isso é algo que você pode fazer em projetos existentes hoje!

Qual é o problema com o JavaScript para loop de qualquer maneira?

O design do for loop incentiva a mutação do estado e o uso de efeitos colaterais , que são fontes potenciais de códigos de buggy e imprevisíveis.

Todos ouvimos que o estado global é ruim e deve ser evitado. No entanto, o estado local compartilha os mesmos males que o estado global , nós simplesmente não percebemos isso muitas vezes porque está em uma escala menor. Então, nunca resolvemos o problema, nós minimizamos isso.

Com um estado mutable, em algum ponto desconhecido, uma variável mudará por um motivo desconhecido e você passará horas a depurar e procurar o motivo pelo qual o valor mudou. Eu já tirei uma dúzia de cabelos da minha cabeça apenas pensando nisso.

Em seguida, gostaria de falar rapidamente sobre efeitos colaterais . Essas palavras soam terríveis, efeitos colaterais. Que nojo. Deseja que seu programa tenha efeitos colaterais? Não, eu não quero que meus programas tenham efeitos colaterais!

Mas o que é um efeito colateral?

Uma função é considerada como tendo efeitos colaterais quando modifica algo fora do escopo da função . Poderia mudar o valor de uma variável, ler a entrada do teclado, fazer uma chamada api, gravar dados no disco, fazer logon em um console, etc.

Os efeitos secundários são poderosos, mas com grande poder é uma grande responsabilidade.

Os efeitos colaterais devem ser eliminados quando possível ou encapsulados e gerenciados. As funções com efeitos colaterais são mais difíceis de testar e difíceis de argumentar , então tire-as sempre que puder. Felizmente, não nos preocuparemos com os efeitos colaterais aqui.

Ok, menos palavras mais código. Vamos dar uma olhada em um for loop típico for loop que você provavelmente já viu milhares de vezes.

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

Meu plano é refatorar este código passo a passo para que você possa ver como é fácil transformar seu próprio código em algo mais bonito.

A primeira mudança que quero fazer é extrair a afirmação if em sua própria função.

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

É uma boa prática em geral extrair suas afirmações if . A mudança na filtragem de "menos de 7 meses" para "é uma gatinha" é um grande negócio. Agora, quando você lê o código, a intenção fica clara. Por que estamos recebendo gatos com menos de 7 meses? Isso não está claro em tudo. Nossa intenção é encontrar gatinhos, então deixe o código dizer isso!

Outro benefício é isKitten agora é reutilizável e todos sabemos,

tornar nosso código reutilizável sempre deve ser um dos nossos objetivos.

A próxima alteração é extrair a transformação (ou mapeamento) de um objeto de tipo gato para um nome. Essa mudança terá mais sentido depois, então, por enquanto, você só precisa confiar em mim.

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

Eu pensei em escrever alguns parágrafos para descrever a mecânica do filter e do map . Mas acho que ao não descrevê-los e, em vez disso, mostrando-lhe com que facilidade você pode ler e entender este código, mesmo sem ter sido introduzido para map ou filter , seria melhor demonstrar como seu código pode se tornar legível.

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

Observe também que eliminamos kittens.push(...) . Não há mais mutação de estado e não mais var !

O código que usa const (sobre var e let) é sexy como o inferno

A divulgação completa aqui, poderíamos ter usado const durante todo o tempo porque const não faz o próprio objeto imutável (mais neste outro tempo). Mas oi, é um exemplo inventado, então me corte uma folga!

A última refatoração que eu sugiro é também extrair a filtragem e o mapeamento para sua própria função (você sabe, para essa coisa de reutilização).

E todos juntos agora:

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

Crédito extra

Para obter crédito extra, leve-o para mais longe Desacoplamento do filter e map métodos de seus objetos. E crédito extra duplo que você poderia pesquisar a composição da função.

JavaScript funcional: métodos de desacoplamento de seus objetos
Uma coisa que eu sempre acabo fazendo no meu projeto é o método de dissociação de seus objetos. mapa, filtro e redução não são … hackernoon.com
JavaScript funcional: composição da função para uso diário.
A composição da função deve ser minha parte favorita da programação funcional. Espero lhe fornecer um bom real … hackernoon.com

E o que é break?

Muitos de vocês perguntaram: "O que é o intervalo?" Verifique a Parte 2: Break é o GOTO de loops. (sugestão: recursão)

Rethinking JavaScript: Break é o GOTO de loops
No meu último artigo, Death of the for Loop, tentei convencê-lo a abandonar o loop para um mais funcional … medium.com

Fim

Por favor, deixe-me saber como você se sente sobre isso nos comentários abaixo. O for loop agora também está morto para você?

Eu sei que é uma coisa pequena, mas faz o meu dia quando recebo as notificações de seguimento no Medium e no Twitter ( @joelnet ). Ou se você acha que estou cheio de merda, fale-me nos comentários abaixo.

Felicidades!

Artigos relacionados

Rethinking JavaScript: a afirmação if
O pensamento funcionalmente abriu minha mente sobre a programação. medium.com
Rethinking JavaScript: elimine a indicação do interruptor para melhor código
Nos meus últimos 3 artigos, convidei você a remover a instrução if, a matar o loop for e nunca usar a quebra. medium.com
JavaScript funcional: resolvendo promessas sequencialmente
Eu adoro a nova biblioteca Promise que vem com o ES6, embora uma coisa tenha sido deixada de fora, uma função para seqüencialmente … medium.com

Este artigo foi traduzido para russo para meus amigos russos.

Hacker Noon é como os hackers começam suas tardes. Somos uma parte da família @AMI . Agora estamos aceitando envios e estamos felizes em discutir oportunidades de propaganda e patrocínio .

Se você gostou desta história, recomendamos ler nossas últimas histórias de tecnologia e histórias de tecnologia de tendências . Até a próxima, não concorde com as realidades do mundo!