Baixe o app para aproveitar ainda mais
Prévia do material em texto
Roger Melo para Escrever Condicionais Eficientes em JavaScript 4 Dicas Práticas Com Exercícios https://rogermelo.com.br/ Nesse eBook eu organizei e disponibilizei um passo-a-passo com técnicas importantes para você escrever estruturas condicionais eficientes em JavaScript. Ao aplicar essas técnicas, seu código fica: Mais Limpo; Mais Legível; ️ Mais Fácil de Testar e Manter. Ao fim de cada capítulo, adicionei exercícios para que você pratique o que leu e comece a aplicar as técnicas em seus projetos. Vem comigo! Bem vindo(a)! Entendendo o switch/case Exercícios Substituindo switch/cases por objetos literais Exercícios Substituindo if’s ou switch/cases por ternários Exercícios Simplificando condicionais Exercícios O que dizem sobre mim 4 24 30 47 52 75 80 117 126 Entendendo o switch / case 04 Neste capítulo, você aprenderá: O que é o switch / case e quando utilizá-lo Como agrupar cases O que é o ‘break’ Quais são as desvantagens em utilizar switch / cases 05 Suponhamos que temos uma função getResponse, que retorna um objeto qualquer do array HTTPresponses. 06 07 Uma forma de executar ações diferentes para cada tipo de resposta desse servidor imaginário, seria utilizar if statements. 08 09 Para esse tipo de caso, onde existe uma lista de múltiplos valores possíveis que podem ser obtidos, o switch/case é uma solução mais elegante e legível. Assim como o if, ele recebe, por parâmetro, o valor que pode ter múltiplas possibilidades que desejamos investigar. 10 11 aqui Se você não entendeu o que está acontecendo na 1ª linha, em resumo, os valores das propriedades 'code' e 'text' do objeto em questão estão sendo atribuídos às consts de mesmo nome. Se quer saber mais, dê uma olhada =D https://twitter.com/rogermelodev/status/1145700971332407296 12 Agora, é possível declarar outros 'case'. Vamos declarar um para o código 404. 13 XXVoltar ao índice Executando esse código, quando há um match com o code '200', o texto do código é exibido 2x no console. Isso aconteceu porque não inserimos um 'break' entre os 'case', então o código abaixo do match foi executado. 14 Executando esse código, quando há um match com o code '200', o texto do código é exibido 2x no console. Isso aconteceu porque não inserimos um 'break' entre os 'case', então o código abaixo do match foi executado. XXVoltar ao índice Executando esse código, quando há um match com o code '200', o texto do código é exibido 2x no console. Isso aconteceu porque não inserimos um 'break' entre os 'case', então o código abaixo do match foi executado. 15 O 'break' é o que vai parar a execução do switch após todo o bloco de código do match ser executado. Voltar ao índice 16 17 Um ponto positivo do switch é a possibilidade de agrupar cases, caso um mesmo bloco de código deva ser executado para valores diferentes. Essa possibilidade deixa o código mais legível, observe: 18 19 Um comparativo entre if e switch: 20 21 É possível ainda declarar um 'default', que é equivalente ao 'else'. Se nenhum 'case' for avaliado como true, o código do default será executado (se ele existir). Note é que é necessário implementar um fallback no destructuring, para que um erro não quebre a aplicação: 22 23 Existem alguns problemas com o switch. Ele possui um fluxo de controle procedural e uma forma não-padrão de conter blocos de código. O design do switch te força a adicionar breaks ou returns dentro do case, o que dificulta o debug, caso você se esqueça deles. Não há nada errado em utilizá-lo, mas quando essa for a sua escolha, certifique-se de que ele é fácil de entender e sua leitura não gera ambiguidades. Spoiler: o próximo capítulo contém dicas para você escrever lógicas similares às do switch, com menos bugs e mais legibilidade! Exercícios 24 25 Escreva um switch/case que dê match com o valor de getday() - próxima página. getday(), quando invocada, retorna um número de 1 à 7. Se o retorno de getday() é 1, exiba no console 'The day is Sunday'. Caso seja 2, a mesma mensagem deve ser exibida, mas o dia deve ser 'Monday'. Essa sequência deve se repetir até 'Saturday', que corresponde ao número 7. Para testar se todos os casos possíveis que você escreveu estão funcionando, após executar o switch pela 1ª vez e ver o resultado no console, modifique o retorno de getDay para um número entre 1 e 7 (pode ser manualmente) e veja se o dia da semana corresponde ao número retornado =) 26 Ver no GitHub https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/01-entendendo-o-switch-case/challenge-01.js 27 Ver no GitHub Agora, à partir do código que você escreveu, organize os dias, dividindo-os entre dias da semana e fim de semana. As mensagens a serem exibidas no console devem ser: - Dias da semana: "It's a weekday." - Fim de semana: "It's a weekend day." https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/01-entendendo-o-switch-case/challenge-02.js 28 Escreva um switch/case que dê match com o valor da propriedade "programming" do objeto stack, na próxima página. As possibilidades a serem cobertas por este match são 'Clojure', 'JavaScript' e 'Python'. As mensagens a serem exibidas devem ser: - Closure: Lisp's dialect. - JavaScript: Often abbreviated as JS. - Python: 'General-purpose programming language.' Não modifique o código que já está escrito. Apenas siga o que os comentários pedem. 29 Ver no GitHub https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/01-entendendo-o-switch-case/challenge-03.js Substituindo switch / cases por objetos literais Neste capítulo, você aprenderá: Por que utilizar objetos Por que as propriedades deste objeto são strings Como refatorar um switch / case Como utilizar fallbacks equivalentes ao 'default' 30 31 No capítulo passado, vimos que utilizar o switch/case traz problemas de fluxo e debug. Neste capítulo, exploraremos a 1ª dica para implementarmos condicionais com menos bugs e mais legibilidade . Vem comigo! 32 Objetos são mais flexíveis, proporcionam legibilidade e manutenibilidade ao seu código. Switch/case statements te obrigam a especificar, manualmente, returns ou breaks. Devido ao uso recorrente de objetos em JavaScript, até um desenvolvedor com conhecimentos mais básicos possui familiaridade com eles, enquanto switch/cases são escritos ocasionalmente. Veremos um exemplo simples, para que você entenda o conceito: Por que objetos? 33 34 Como refatorar o switch/case da função? Declarando um objeto em que cada 'case' seja uma propriedade: 35 36 Já ficou mais legível Agora, precisamos implementar o retorno da função, que é a propriedade que dá match com o parâmetro que ela recebe: 37 38 Por que existe o risco do argumento passado na invocação da função não ser um identificador JavaScript válido. Nenhuma das propriedades à seguir, por exemplo, pode ser escrita como uma propriedade padrão: Mas por que as propriedades deste objeto são strings? 39 40 A notação utilizada no retorno da função permite o uso de caracteres que não podem ser utilizados com a notação 'object.property'. Notações de acesso à propriedades são uma discussão extensa e renderiam um capítulo exclusivo. Mas era importante esclarecer esse detalhe. 41 E se o 'type' não der match com alguma propriedade do objeto? A função retornará 'undefined'. Evitamos isso implementando um fallback, equivalente ao 'default' do switch/case. Se a expressão à esquerda do operador 'or' for truthy, a expressão é retornada. Caso contrário, a expressão à direitaé retornada: 42 43 Primeiro, fazemos a função retornar o objeto diretamente, sem armazená-lo em uma const. Como precisamos retornar o valor de uma propriedade, basta encadear a notação de colchetes no objeto: Podemos melhorar esse código? Claro! 44 45 Podemos ainda evitar o uso do 'return', utilizando uma arrow function: 46 Exercícios 47 48 No código à seguir, abaixo da função getDefaultMessage, declare a função que está sendo invocada na penúltima linha, `getFruitColor`. Essa função irá encapsular o switch/case que você escrever. Este switch/case deve dar match com as frutas do array. Ao dar match, a função `getFruitMessage` deverá retornar a mensagem de acordo com a cor da fruta. Teste o código no console. O resultado deve ser a seguinte string: 49 Strawberry is a red fruit. Kiwi is a green fruit. Banana is a yellow fruit. Escreva também uma alternativa em que o match com a fruta não aconteça. Já existe uma função que retorna uma mensagem desse tipo... Tudo certo até aqui? Vamos para a 2ª etapa =D 50 [ ] Refatore o switch/case para um objeto, implementando também um fallback equivalente ao 'default'. Dica: envolva as keys do seu objeto em colchetes: propertyName : 'property value' Essa feature se chama Dynamic Property Keys. Ela possibilita que você utilize uma variável como propriedade do objeto =) Teste seu código no console. 51 Ver no GitHub https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/02-substituindo-switch-cases-por-objetos-literais/challenge.js Substituindo if’s ou switch / cases por ternários Neste capítulo, você aprenderá: Quando utilizar essa técnica Como o ternário funciona As vantagens e desvantagens em utilizá-lo 52 53 Chegou a hora de você conhecer mais uma dica prática para escrever condicionais eficientes, e utilizá-la à partir de hoje. Pronto para repensar essa parte do seu código? Vem comigo! 54 Aviso: isso não vale para todos os casos. Meu objetivo é fazer você refletir e entender em qual momento a implementação dessa técnica é bem-vinda ou não. Sempre avalie o seu contexto =) Substituindo if's por ternários 55 Primeiramente, conheça o potencial substituto de ifs e switch/cases, o operador condicional ternário: 56 57 O que está acontecendo nesse código? Se 'condition' for true, 'expression1' é executada. Caso contrário, quem será executada é a 'expression2'. 58 São mais simples de ler e entender do que if’s e switch/cases (opinião pessoal); Você escreve menos; São uma expressão, e não um statement. Quais são as vantagens em utilizar ternários? 59 Expressões x Statements rendem um capítulo por si só, mas o que quero extrair desse tema é que blocos são inflexíveis. Um bloco é um conjunto de statements que não pode ser retornado ou atribuído à uma variável, por exemplo. 60 61 Vamos à outra comparação simples. Temos um if que executa uma ação caso o número recebido seja maior do que 5. Caso contrário, uma outra ação é executada: 62 63 Essa simples operação fez você escrever 5 linhas de código. Com o ternário, a implementação fica assim: 64 65 Como o ternário é uma expressão, e não um statement, é possível atribuí-lo à variáveis: 66 67 Ou implementá-lo em apenas uma parte de uma instrução: 68 69 Se podemos encadear if/elses ou switch/cases, também podemos encadear expressões ternárias =) Vejamos um exemplo diretamente do website do Redux, utilizando switch/case: 70 71 É possível implementar essa lógica com ternários encadeados, onde as condições substituem os 'case': 72 73 Uma das desvantagens em utilizar ternários é que não é possível fazer verificações para apenas uma condição. Fique atento a isso. 74 Exercícios 75 76 No código à seguir, escreva um if/else abaixo da função 'isGreaterThanFour' que: - Verifique se 'quantity' é maior que 4. Se for, exiba no console a mensagem "[X] é maior que 4.". "[X]" deve ser o número que está sendo verificado (quantity). - Caso contrário, exiba a mensagem "O número é menor que 4." - Para evitar a repetição do 'console.log()', crie uma função 'showMessage' abaixo de 'isGreaterThanFour' e antes do if. - Essa função deve receber, por parâmetro, a mensagem a ser exibida. Depois de testar esse if/else, refatore-o para ternário =) 77 Ver no GitHub https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/03-substituindo-ifs-ou-switch-cases-por-ternarios/challenge-01.js 78 No código à seguir, refatore o if / else-if / else utilizando ternários encadeados. Para evitar a repetição do 'userPosition === XXX', escreva uma função que retorne o resultado dessa verificação. 79 Ver no GitHub https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/03-substituindo-ifs-ou-switch-cases-por-ternarios/challenge-02.js Simplificando condicionais Neste capítulo, você aprenderá: Evitar if/elses desnecessários Encurtar estruturas condicionais sem perder a legibilidade Simplificar if’s aninhados Testar arrays sem utilizar if’s e loops 80 81 Você já se deparou com uma estrutura condicional como à seguir? Já sentiu seu coração disparar e o olho pular enquanto lê esse tipo de código? 82 83 Peguei pesado, né? Então primeiro, veremos um exemplo mais simples =) 84 Se 'car' é um objeto e queremos exibir o nome do carro, mas também testar se o objeto foi passado por argumento, é possível escrever uma estrutura condicional assim: Evitando if/elses desnecessários 85 86 Só que esse if/else pode ser completamente evitado, utilizando default parameters, destructuring e arrow function, para você escrever menos: 87 88 aqui Se você não entendeu o que está acontecendo na declaração de parâmetros dessa função, dê uma olhada =D https://twitter.com/rogermelodev/status/1145700971332407296 89 E quando queremos verificar múltiplas possibilidades? Vamos passar uma string por argumento, ao invocar a função: Encurtando estruturas condicionais, sem perder a legibilidade 90 91 Se as possibilidades de valores da string aumentam, o if tem mais 'or' operators e fica ainda mais ilegível: 92 93 Como solucionar isso? Uma possibilidade: mover as strings para um array e fazer a verificação através do método includes(). 94 95 Condicionais aninhadas são problemáticas por que dificultam determinar o fluxo normal do código. Cada condição é um paliativo, adicionando complexidade à otimização da estrutura. Veja à seguir, ele possui 1 if/else e 3 níveis de if’s aninhados: Simplificando condicionais aninhadas 96 97 Uma técnica para começar a refatorar esse tipo de código é pará-lo, imediatamente, após uma condição inválida ser encontrada: 98 99 Ou seja, já conseguimos diminuir a estrutura condicional de 3 níveis para 2, e removemos o else. É possível ainda mover o if de 2º nível para fora do if que o envolve, utilizando o operador de negação caso 'car' não exista no array: 100 101 O 1º if assegura que caso 'car' seja 'falsy', como 'null' ou 'undefined', o código é, imediatamente, interrompido e uma resposta é retornada. Usei console.log para focarmos apenas nas estruturas condicionais =) Vamos assegurar que caso o parâmetro 'quantity' não seja especificado, o valor dele seja 1 por padrão: 102 103 É possível eliminar a const 'amount', utilizando default parameters: 104 105 Cada parâmetro pode ter seu valor default. Podemos fazer com que, se 'car' não for especificado como 1º argumento da invocação da função, 'No car was especified' seja exibido. Com isso, removemos o 1º if: 106 107 Agora que temos apenas 1 nívelde ifs, é possível refatorarmos o código, quebrando-o em pequenas funções: 108 109 2: O nome do carro ou a mensagem default sempre são exibidos; 4 a 7: Se o carro não foi encontrado no array, a mensagem 'Car not found.' é exibida e o código abaixo é ignorado; 9 e 10: Se o carro foi encontrado, as duas funções são executadas. Não precisamos do 'else'. O código ficou maior, porém mais legível. Nada de Pyramid of Hell aqui . Antes e depois: O que está acontecendo nas linhas desse código 110 111 E se temos que testar um array de objetos? Vamos testar se todos os objetos do array possuem uma propriedade específica, com 1 valor específico. Escrevendo da forma "tradicional", com um loop e um if: Testando um array sem utilizar if’s e loops 112 113 É possível removermos o ‘for’ e o ‘if’ deste código. Utilizaremos o método 'every()', para verificarmos se todas as propriedades 'color' dos objetos do array possuem o mesmo tipo e valor: 114 115 Utilizando o método '.some()', conseguimos verificar se alguma das propriedades 'color' dos objetos do array possui o mesmo tipo e valor especificado: 116 Exercícios 117 118 Considerando o código à seguir, refatore os '||' que o if possui e exiba o resultado no console. 119 Ver no GitHub https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/04-simplificando-condicionais/challenge-01.js 120 Refatore o código à seguir, eliminando o if/else, mas mantendo a mesma lógica. Exiba o resultado no console. 121 Ver no GitHub https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/04-simplificando-condicionais/challenge-02.js 122 Refatore o código à seguir, removendo o 'for' e o 'if', mas mantendo a mesma lógica de testar todos os itens do array. Exiba, no console, o valor booleano que indica se todos os Filmes são da Disney. 123 Ver no GitHub https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/04-simplificando-condicionais/challenge-03.js 124 Exiba, no console, o valor booleano que indica se algum dos jogos foi publicado pela Nintendo. 125 Ver no GitHub https://github.com/Roger-Melo/ebook-4-dicas-praticas/blob/master/challenges/04-simplificando-condicionais/challenge-04.js O que dizem sobre mim 126 127 Ver no Twitter Ver no Twitter Ver no Twitter Ver no Twitter https://twitter.com/apertaoesc/status/1167621988493529090 https://twitter.com/felipefialho_/status/1163787907997536256 https://twitter.com/ogiovannilima/status/1164304977583583232 https://twitter.com/adrianoneres/status/1164610233450323970 Postagens que originaram esse eBook 128 129 12 tweets para entender o switch/case 3 dicas práticas para escrever condicionais eficientes - Parte 1 3 dicas práticas para escrever condicionais eficientes - Parte Final 3 dicas práticas para escrever condicionais eficientes - Parte 2 Ver Thread Ver Thread Ver Thread Ver Thread https://twitter.com/rogermelodev/status/1149696959441244160 https://twitter.com/rogermelodev/status/1151299367535595520 https://twitter.com/rogermelodev/status/1152362637335912449 https://twitter.com/rogermelodev/status/1154508362844954625 130 Espero que este eBook tenha trazido técnicas úteis para você aplicar no dia-a-dia, em seus projetos . Se você tem alguma dúvida, sugestão ou feedback, fique à vontade para me enviar um email ou me chamar no Twitter =D Conte comigo para ser um(a) Desenvolvedor(a) JavaScript acima da média e conquistar seus objetivos! Parabéns por chegar até aqui! rogermelodevrogermelo.com.br https://rogermelo.com.br/ https://twitter.com/rogermelodev Roger Melo https://rogermelo.com.br/
Compartilhar