Olá, sou o Arthur! ----------------------
Meu nome é Arthur Lima e sou desenvolvedor aqui na nata.house! Amo a área de programação e tecnologia, e sempre me empolgo com qualquer novidade. Curto bastante jogos indies e ouvir cloud rap enquanto trabalho. Fui convidado para escrever um pouco sobre boas práticas em JavaScript que atualmente é a linguagem que mais utilizo no dia a dia, é minha primeira vez escrevendo um post tão importante (tô nervouser), por isso pesquisei bastante e vou tentar o meu melhor pra passar da melhor forma esse conteúdo de grande relevância. Espero que gostem!
O que são boas práticas?
São um conjunto de regras criadas por algum tipo de comunidade a partir do tempo de uso de determinada tecnologia ou ferramenta, que visa melhorar a qualidade do código e do produto final.
Para que serve?
Seguir boas práticas é essencial, principalmente na área de programação onde existem várias formas de executar a mesma tarefa. Essas práticas, além de ajudar a evitar erros comuns, também facilitam a manutenção do código e ajudam na legibilidade do mesmo.
“Legibilidade do código?” você deve estar se perguntando. Exatamente! É uma boa prática escrever nosso código de uma forma que seja fácil de outra pessoa que for utilizar nosso código ou encontrar um bug. Como a maioria do tempo que passamos codando é justamente dando manutenção em um código, a primeira coisa que deveríamos aprender é como escrever de uma forma que faça com que a manutenção seja mais simples e rápida, ajudando, assim, o seu coleguinha ou até mesmo o seu eu do futuro.
Essa questão de legibilidade é tão importante que existem ferramentas específicas para nos auxiliar, como o Prettier que serve para formatar seu código de acordo com regras definidas anteriormente. Poupando, assim, o trabalho da correção em uma review, isso de forma automatizada (é só dar um save que ele deixa seu código arrumadim).Outra ferramenta que pode te ajudar é o ESLint, que aponta erros de indentação ou erros de sintaxe enquanto você coda, e ainda te dá a opção de seguir os padrões estipulados por grandes empresas, como o Airbnb, e até mesmo a própria Google.
Como isso pode me ajudar?
Programar pensando na futura manutenção não auxilia somente sua equipe, mas também o seu “eu” de alguns meses ou anos para frente, pois provavelmente você sofrerá bastante para fazer alguma alteração em um código mal escrito, que possui alta probabilidade de apresentar bugs.
Afinal, quem nunca pegou um código gigantesco, repetido 3 vezes no mesmo arquivo, mau indentado e pensou: “Nossa, quem foi que escreveu isso?” e foi acusado pelo git blame que foi você mesmo 3 meses atrás?
Vale lembrar também que as convenções de uma linguagem podem não ser aplicáveis em outra linguagem ou ferramenta, variando de acordo com o contexto ou tamanho do projeto. Por isso, não faz sentido tentar usar as boas práticas de uma linguagem com um paradigma orientado a objeto em uma linguagem de paradigma funcional.
Nesse post vamos abordar algumas convenções da linguagem JavaScript, com dicas para te ajudar a criar essa cultura de boas práticas no seu dia a dia pra você deixar o pleno de boca aberta! Vamos lá?!
1- DRY
DRY significa Don’t Repeat Yourself (não se repita), que é um princípio de desenvolvimento de software que diz:
“Cada parte do conhecimento deve ter uma representação única, não ambígua e definitiva dentro do sistema.”
A ideia é diminuir o código repetido e redundante em vários outros lugares do projeto. E ter código duplicado significa que existe mais de um lugar onde você deverá alterar se precisar mudar alguma lógica. Quando aplicado corretamente, caso precise fazer uma alteração em qualquer elemento do código, você só precisará alterar este elemento do código e nenhum outro.
Ele também ajuda a modularizar seu código, já que se você precisa usar uma mesma lógica várias vezes você provavelmente criará uma função ou uma rotina para facilitar a execução dessa lógica, facilitando futuros usos no sistema, até mesmo por outros devs do seu time! Então na próxima vez que você for dar um ctrl+c ctrl+v em algum código, lembre-se desse princípio! 😉
2- Usar === ao invés de ==
Primeiramente precisamos entender a diferença entre as duas formas de comparação. Ao usar “==” é comparado se o valor dos dois argumentos batem, enquanto ao usar o “===” a comparação dos valores é se são estritamente iguais ou identicamente iguais, portanto, também é feita a checagem do seu tipo. Vamos aos exemplos para entendermos melhor:
Ao usar o “==” forçamos uma conversão dos valores para fazer a comparação como no exemplo acima ao comparar um number com uma string. Mesmo isso parecendo ser uma boa coisa, isso pode nos trazer alguns problemas em casos específicos que não podemos ter certeza no que pode resultar:
Assim, ao utilizar a comparação de “===” temos muito mais certeza que o nosso código não passará por conversões ou valores imprevisíveis, resultando em um código muito mais preciso em relação a tipagem, que no JavaScript sabemos que é dinâmica. Ao utilizarmos a comparação “idêntica” podemos ver como o retorno dos exemplos anteriores são completamente diferentes:
Vale lembrar que isso também funciona com as comparações de negação, ou uma inequação (!= vs !==). Muito interessante, não é?
3- Evitar variáveis globais
Variáveis globais são aquelas que declaramos no escopo universal da aplicação, sendo possível acessá-la de qualquer lugar. Quando utilizamos variáveis globais, declarando um var por exemplo, estamos expondo um endereço de memória reservado para aquela variável para a nossa aplicação inteira, existindo a possibilidade da mesma ser sobrescrita por outra parte do código ou por outro script usado na mesma página.
Não é errado usar variáveis globais, porém a a chance dela ter seu valor substituído sem termos o controle disso é alta, e isto é muito ruim para a manutenção do código e aumenta as chances de bugs. Portanto, uma saída de último caso é conter o escopo dessa variável utilizando um wrapper, como podemos ver no exemplo:
Agora para acessar a variavelGlobal1, basta usar wrapper.variavelGlobal1.
4- Declaração literal ao invés de new Object()
Existem algumas formas de declarar esses tipos de variável, vamos abordar a forma de construtor e a notação literal. Ao utilizar a forma de construtor, criamos uma variável do tipo objeto passando seu conteúdo para a variável diretamente.
Quando a variável a ser criada é do tipo objeto ou array a forma mais recomendada é a chamada literal, que é quando você usa as chaves (ou parênteses) para atribuir valores ao mesmo tempo da declaração. Por exemplo:
Além de melhorar na legibilidade, nos ajuda a separar melhor o código por responsabilidades, ajudando também na organização da aplicação.
5- Siga a arquitetura do projeto
Se o projeto que você acabou de entrar já está em andamento, reserve um tempo para entender como ele funciona, quais os seus padrões e como fazer cada coisa. É de suma importância que o seu código do projeto inteiro seja organizado e siga as mesmas normas para não atrapalhar na hora do trabalho em equipe do time, e isso vale desde a estrutura de pastas até como estão sendo criadas as funções de “helpers”. Vale ressaltar que mesmo assim é muito produtivo que você tente disseminar as boas práticas entre o time, para que o padrão a ser seguido nos projetos seja a mesma proposta pela linguagem ou ferramenta.
6- Funções Puras
Vários conceitos de programação funcional estão sendo popularizados. Um dos principais é o de funções puras, que consiste em uma função que dado uma entrada, independente do contexto ou do número de vezes que ela for chamada irá sempre retornar o mesmo resultado, sempre! Isso também significa que a função não sofrerá nenhum efeito colateral em sua execução. Um exemplo de função não pura:
Nesse caso, a função necessita de uma variável idade ter sido declarada anteriormente, não podendo ser usada em qualquer tipo de contexto causando um efeito colateral, já que caso seja atribuído um valor do tipo string poderá causar erros na aplicação.
Agora um exemplo de função pura:
Seguindo o mesmo objetivo do exemplo anterior, podemos ver que agora retornamos um valor dependendo da entrada que a função receber, e independente de onde ela for chamada, com os mesmos parâmetros sempre retornará o mesmo resultado. Vale lembrar que para que não haja efeitos colaterais também é recomendado não alterar suas entradas, e que não faça nenhuma alteração fora do seu escopo.
7- Tente sempre uma abordagem mais “pura” ao invés de utilizar bibliotecas
Quando você adiciona uma biblioteca na sua aplicação, é claro que o objetivo é tentar reduzir a quantidade de trabalho que você teria ao fazer aquela tarefa manualmente. Porém, muitas delas podem adicionar um tamanho extra no seu produto final e talvez você não esteja usando realmente tudo que a biblioteca tem para te oferecer. Portanto, sempre antes de adicionar uma biblioteca extra, pense se não teria uma forma de você implementar a mesma funcionalidade manualmente em JavaScript. Isso te ajuda tanto contribuindo com o seu aprendizado , porque você estará tentando reimplementar algo que você até então não faz ideia de como funciona, como também diminui a carga que o seu bundler terá com mais uma biblioteca para carregar.
Dica extra: a medida que você for criando essas implementações, pergunte se alguém não consegue te ajudar a resolver o problema e compartilhe seu repositório de “utilitários” com o time e incentive que eles façam o mesmo. Quando você perceber vocês terão uma biblioteca própria!
8- Nomeie bem suas variáveis
Quem nunca se deparou com uma variável chamada “data”, que poderia realmente ter um array de dados, ou um booleano pra informar que alguma função foi executada, ou até mesmo um objeto do tipo Date? Essa boa prática ataca exatamente esse ponto, para deixar a manutenção ou a adição de novas features seja um trabalho mais tranquilo e intuitivo.
Segue algumas dicas:
- Funções: use verbos para denotar ações! Ex: doLogin, make
- Objetos: use substantivos. Ex: person, user, car
- Valores booleanos: indique a capacidade da sua expressão usando os prefixos has, is, can, isThere, allow e try
9- Mudança contínua
Como na nossa área tudo se atualiza rapidamente, é necessário sempre se atualizar também sobre as novas funcionalidades que a linguagem ou ferramenta lança a cada versão. Assim o código do seu projeto fica mais atual e fácil de manter. Isso também poderia ser uma boa prática! 🙂
10- Adaptação e flexibilidade
Apesar de uma boa prática ter seu potencial validado e testado em várias ocasiões diferentes, pode ser que mesmo assim ela não se encaixe no dia a dia do seu time ou no contexto do seu projeto. É possível que sua equipe adapte uma convenção para funcionar melhor com as pessoas envolvidas no time, ou até mesmo a não adoção de algum ponto, ninguém vai ser preso por isso. Mas se você usar um var, eu chamo a polícia!
Existem vários outros tópicos que poderiam ser abordados, e também outros pontos que são até controversos de tanta complexidade, mas todas essas normas existem justamente para tornar o uso da linguagem JavaScript e todas já foram totalmente exploradas por outros profissionais que já otimizam o uso da linguagem todos os dias, mas ainda assim existem desenvolvedores que não seguem esses conceitos.
Abordamos neste post vários conceitos e dicas para tornar seu código mais limpo, de maior manutenibilidade e até mesmo mais profissional! Se você seguir algumas dessas dicas você com certeza se tornará um melhor desenvolvedor JavaScript, e se aproximará da sua excelência como um todo a cada dia de prática!
Lembre-se também de sempre ter orgulho do seu código!