JavaScript é uma linguagem de programação extremamente flexível usada para construir praticamente qualquer coisa que você possa imaginar, de sites, aplicativos da web e aplicativos de desktop a UIs para dispositivos inteligentes, aplicativos do lado do servidor, e muito mais.
A flexibilidade do JavaScript é o que permitiu seu amplo conjunto de recursos-mas, como sabemos, também é responsável por alguns comportamentos estranhos que acendeu a imaginação dos desenvolvedores. Parte do código que escrevemos é exclusivamente adequado para resolver esses problemas estranhos de maneiras inteligentes e elegantes; alguns não.
Neste artigo, vamos nos concentrar na análise das diferentes maneiras pelas quais os desenvolvedores substituíram instruções condicionais prolixas e confusas-em particular, as instruções if/else if
e switch
em cascata. Por quê? Porque em JS, podemos fazer melhor do que apenas usar if
.
Operadores
ternário, &&
e ||
Vamos introduzir uma função simples com uma instrução condicional usando if
e vamos refatorá-la usando o operador ternário .
if (condição) { return functionTrue (); } senão { return functionFalse (); }
Não há nada de errado com nosso exemplo acima, mas ocupamos desnecessariamente algumas linhas de código repetindo a palavra-chave return
. O operador ternário permite simplificação:
condição de retorno? functionTrue (): functionFalse ();
Não é muito mais simples? Mas como isso funciona?
O operador ternário é o único operador JavaScript que aceita três operandos: uma condição seguida por um ponto de interrogação (?
), uma expressão para uma condicional verdadeira seguida por dois pontos (:
) e, finalmente, uma expressão para uma condicional falsa. Aqui está o que parece:
condição? expressionIfTrue: expressionIfFalse
Observe que as expressões true
e false
devem ser fornecidas para que o operador ternário funcione. Mas e se só precisarmos fazer algo quando a condição for verdadeira?
JavaScript oferece métodos alternativos de simplificação de expressões usando os operadores &&
e ||
.
Vejamos um exemplo diferente em que só precisamos executar uma instrução quando a condição for satisfeita.
if (condição) { console.log ("é verdade!"); }
Poderíamos reescrever esta declaração em uma linha usando &&
, assim:
condição && console.log ("é verdade!");
O principal motivo para isso funcionar é que o JavaScript lê os operandos em declarações condicionais da esquerda para a direita e sai no momento em que pode invalidar os argumentos. Portanto, no caso de &&
, se a primeira declaração for falsa, não há sentido em avaliar a próxima, já que toda a expressão é falsa.
Da mesma forma, o operador ||
continuará avaliando os operandos até que um deles seja true
ou toda a expressão seja avaliada como false
. Dê uma olhada no exemplo abaixo:
trueCondition || console.log ("Olá, mundo!");//não executa o console.log falseCondition || console.log ("Olá, mundo!");//executa o console.log
Avaliação de vários resultados para uma expressão
Freqüentemente, quando estamos lendo ou escrevendo código, encontramos várias condições if
aninhadas-como na função a seguir, que pega o nome de uma fruta e retorna sua cor.
function getColor (fruit) { if (fruit.toLowerCase ()==='apple') { return'red'; } else if (fruit.toLowerCase ()==='banana') { retornar'amarelo'; } if (fruit.toLowerCase ()==='laranja') { retornar'laranja'; } if (fruit.toLowerCase ()==='blueberry') { retornar'azul'; } if (fruit.toLowerCase ()==='limão') { retornar'verde'; } retornar'desconhecido'; }
Mesmo quando o código executa sua função conforme o esperado, há várias coisas que podemos fazer melhor. Para começar, o método toLowerCase
está sendo chamado várias vezes para cada fruta, o que pode não apenas afetar o desempenho, mas também tornar toda a função menos legível.
A próxima otimização seria evitar a repetição das condicionais, o que reduz o número de instâncias em que poderíamos introduzir erros, como esquecer de incluir o método toLowerCase
em uma de nossas linhas.
Podemos corrigir isso rapidamente chamando o método apenas uma vez no início da função e avaliando cada resultado-mas podemos fazer ainda melhor usando um switch
declaração.
function getColor (fruit) { switch (fruit.toLowerCase ()) { case'apple': return'red'; caso'banana': retornar'amarelo'; caso'laranja': retornar'laranja'; case'blueberry': retornar'azul'; caso'cal': retornar'verde'; padrão: retornar'desconhecido'; } }
Parece muito melhor, mas ainda não parece certo. Existem muitas palavras-chave repetidas, o que torna a leitura confusa.
Abaixo está uma abordagem diferente-uma abordagem mais inteligente e elegante, como discutimos no início deste artigo.
function getColor (fruit) { frutas const={ 'maçã':'vermelho', 'banana':'amarelo', 'laranja':'laranja', 'mirtilo':'azul', 'verde limão', }; retornar frutas [fruit.toLowerCase ()] ||'desconhecido'; }
Simplesmente lindo. É fácil identificar qual fruta corresponde a cada cor, não estamos repetindo palavras-chave e isso é claramente lido e compreendido.
Este método para resolver instruções if
em cascata é denominado Jump Table. Pode funcionar para muito mais do que simples textos ou constantes; vamos ver um exemplo mais complexo.
Construindo objetos de mapa
A abordagem Jump Table é ótima para textos e constantes simples, mas como funcionaria em situações mais complexas, como quando as instruções if
têm várias linhas de código com chamadas de função?
Agora que entendemos como simplificar as declarações, a abordagem para esses cenários mais complexos é direta-trata-se de como construímos nosso objeto Mapa.
Vamos construir uma função calcular
com dois números e uma operação como argumento e retornar o resultado da operação sobre os dois números.
função
calcular (número1, número2, operação) { operações const={ '+': (a, b)=> a + b, '-': (a, b)=> a-b, '*': (a, b)=> a * b, '/': (a, b)=> a/b, } operações de retorno [operação]?. (número1, número2) ??'operação inválida'; }
Como esperado, o código parece muito limpo e uma função é claramente atribuída a cada operação para realizar os cálculos necessários para obter o resultado desejado.
O que parece um pouco diferente, e talvez estranho, é a instrução return
; mas a ideia por trás disso é simples, então vamos decompô-la.
operações [operação]?. (número1, número2)
A primeira parte da expressão simplesmente retornará a operação fornecida do dicionário e executará a função se a chave estiver presente. Se a chave não existir, ele retornará undefined
. Esta última parte é graças ao encadeamento opcional operador .
A segunda parte usa o operador de coalescência nulo , que retorna seu operando do lado direito quando o operando do lado esquerdo é null
ou undefined
e, caso contrário, retorna seu operando do lado esquerdo operando do lado manual.
??'operação inválida';
Portanto, em nosso caso, ele retornará o resultado da operação quando a operação estiver presente no dicionário, ou retornará uma operação inválida
.
Conclusão
JavaScript é uma linguagem flexível que oferece várias maneiras de resolver um problema. Neste artigo, aprendemos várias alternativas às instruções if
tradicionais que podem ajudá-lo a escrever um código melhor e mais claro.
É importante ter várias opções em seu arsenal de código porque não existe uma solução única que seja certa para cada situação. Além disso, o JavaScript está evoluindo e novas maneiras serão introduzidas ou descobertas à medida que novas versões forem lançadas, então é útil ficar conectado e ler os artigos mais recentes para se manter atualizado.
Obrigado por ler!
A postagem Refatorando condicionais em cascata em favor da legibilidade apareceu primeiro em LogRocket Blog .