Todo mundo quer ser um especialista. Mas o que isso significa? Ao longo dos anos, encontrei dois tipos de pessoas chamadas de "especialistas". Um especialista do primeiro tipo é uma pessoa que não apenas conhece todas as engrenagens da língua, mas também usa todas essas engrenagens, independentemente de serem benéficas. Um especialista do segundo tipo também conhece todas as sutilezas sintáticas, mas é mais seletivo na escolha de uma ferramenta para resolver um problema, levando em consideração uma série de fatores, relacionados ou não ao código.
Vamos adivinhar que tipo de especialista você gostaria de ver em sua equipe. Em segundo lugar, certo? Este é o tipo de desenvolvedor que se esforça para produzir código legível por humanos, strings de JavaScript que outras pessoas possam entender e que sejam fáceis de manter. Mas a característica "legível" raramente é definidora - na verdade, geralmente está nos olhos de quem vê. Então, aonde isso nos leva? O que devemos buscar se nosso objetivo é um código legível? Existe uma escolha claramente certa ou errada neste caso? Depende muito.
A escolha óbvia
Para tornar o trabalho do desenvolvedor mais fácil, o TC39 adicionou muitos novos recursos ao ECMAScript nos últimos anos, incluindo muitos padrões comprovados emprestados de outras linguagens. Uma dessas inovações introduzidas no ES2019 é o método Array.prototype.flat () . Leva um argumento de profundidade ou infinito e alinha a matriz. Se não houver argumentos, a profundidade padrão da matriz é 1.
Antes que essa adição aparecesse, a seguinte sintaxe era necessária para alinhar a matriz em um único nível.
let arr = [1, 2, [3, 4]];
[].concat.apply([], arr);
// [1, 2, 3, 4]
Adicionando flat (), você pode descrever o mesmo recurso com apenas uma função expressiva.
arr.flat();
// [1, 2, 3, 4]
A segunda linha de código é mais fácil de ler? Absolutamente sim. Na verdade, ambos os especialistas concordariam com isso.
Nem todo desenvolvedor está ciente da existência de flat (). Mas não é necessário saber sobre isso com antecedência, uma vez que flat () é um verbo compreensível, do qual fica claro o que está acontecendo aqui. É muito mais intuitivo do que concat.apply ().
Este é o caso raro em que você pode responder com segurança qual sintaxe é melhor - nova ou antiga. Ambos os especialistas, tendo se familiarizado com as duas sintaxes, escolherão a segunda. Eles escolherão a linha de código que é mais curta, mais clara e mais fácil de manter.
Mas a escolha e o compromisso nem sempre são tão simples.
Verifique se há piolhos
O que é maravilhoso em JavaScript é sua incrível versatilidade. É por isso que está em toda parte na web. Se é bom ou ruim do seu ponto de vista, é outra questão.
Mas essa versatilidade traz consigo o paradoxo da escolha. O mesmo código pode ser escrito de muitas maneiras diferentes. Como você determina qual é a "correta"? Essa solução nem pode ser abordada se você não conhece todas as opções disponíveis e não entende o que elas não alcançam.
Vamos tentar a programação funcional com map () como exemplo. Percorrerei algumas iterações aqui - todas levarão ao mesmo resultado.
Esta é a versão mais concisa de todos os nossos exemplos de map (). Possui o menor número de caracteres e todos cabem em uma linha. Vamos construir nesta versão.
const arr = [1, 2, 3];
let multipliedByTwo = arr.map(el => el * 2);
// multipliedByTwo [2, 4, 6]
O exemplo a seguir adiciona apenas dois caracteres: parênteses. Perdemos alguma coisa? Você comprou? O clima torna sempre necessário o uso de parênteses em uma função que possui mais de um parâmetro? Eu acho - sim, é verdade. Não há nada de errado em adicioná-los aqui, mas a consistência do código aumentará significativamente quando você inevitavelmente precisar escrever uma função com muitos parâmetros. Na verdade, no momento em que este livro foi escrito, Prettier acabou sendo obrigado a ter essa restrição; ali não consegui criar uma função de seta sem parênteses.
let multipliedByTwo = arr.map((el) => el * 2);
Vá em frente. Adicionamos chaves e uma instrução de retorno. Isso agora está começando a soar como uma definição de função tradicional. No momento, pode parecer uma palavra-chave, desde que toda a lógica da função seja disparar um canhão contra pardais. Mas, se a função contiver mais de uma linha, essa sintaxe adicional será definitivamente necessária. Estamos assumindo que não teremos nenhuma outra função com mais de uma linha? Parece duvidoso.
let multipliedByTwo = arr.map((el) => {
return el * 2;
});
Em seguida, removemos a função de seta por completo. Usamos a mesma sintaxe de antes, mas agora preferimos a palavra-chave de função. Isso é interessante porque não há cenário em que essa sintaxe não funcione; para qualquer número de parâmetros ou strings, não teremos problemas, então aqui somos fortes em uniformidade. Este código é mais longo do que nossa primeira definição, mas é realmente tão ruim assim? Como isso prejudica um novo programador ou alguém que não é especialista em JavaScript, mas em alguma outra linguagem? Alguém com um bom conhecimento de JavaScript ficaria confuso com essa sintaxe durante a comparação?
let multipliedByTwo = arr.map(function(el) {
return el * 2;
});
Finalmente, chegamos à última opção: passe apenas uma função. E o timesTwo pode ser escrito usando qualquer sintaxe que quisermos. Novamente, não há cenário em que passar o nome da função acabe sendo um problema para nós. Mas vamos dar um passo atrás e pensar se esse código poderia confundir alguém. Se você está apenas começando com esta base de código, está claro para você que timesTwo é uma função, não um objeto? Definitivamente, map () servirá como uma dica aqui, mas esse detalhe pode passar despercebido. Que tal onde timesTwo é declarado e inicializado? É fácil encontrar? Está claro o que isso faz e como afeta o resultado? Todas essas considerações são importantes.
const timesTwo = (el) => el * 2;
let multipliedByTwo = arr.map(timesTwo);
Como você pode ver, não há uma resposta óbvia aqui. Mas escolher as opções certas ao construir sua base de código só é possível se você compreender todas as opções e suas limitações. Em particular, você sabe que precisa de parênteses, chaves e palavras-chave de retorno para tornar seu código consistente.
Há uma série de questões a serem abordadas ao escrever o código. Os problemas de desempenho geralmente são os mais comuns. Mas, ao comparar fragmentos de código funcionalmente idênticos, a escolha deve ser feita com atenção às pessoas que terão que ler esse código.
Talvez o mais recente nem sempre seja melhor
Portanto, vimos um exemplo muito pronunciado em que ambos os especialistas preferem a sintaxe mais recente, mesmo que não seja bem conhecida. Também vimos um exemplo que faz muitas perguntas, mas não fornece muitas respostas. Agora vamos mergulhar no código que escrevi antes ... e excluí. Esse código me transformou em um especialista do primeiro tipo quando resolvi o problema com uma construção sintática pouco conhecida, negligenciando meus colegas e a conveniência de manter nossa base de código.
A atribuição de desestruturação permite desempacotar valores de objetos (ou matrizes). Geralmente é algo assim.
const {node} = exampleObject;
Aqui, em uma linha, uma variável é inicializada e atribuída um valor. Mas pode não ser o caso.
let node
;({node} = exampleObject)
Na última linha do código, o valor é atribuído a uma variável usando a desestruturação, mas a variável é declarada uma linha acima. Isso é feito com frequência, mas muitos não percebem que isso é possível.
Vamos dar uma olhada neste código. O ponto-e-vírgula estranho é imposto aqui, e isso está no código onde o ponto-e-vírgula não é usado para encerrar linhas. Aqui, o comando é colocado entre parênteses e as chaves são adicionadas; é completamente incompreensível o que está acontecendo aqui. É difícil ler esta linha porque, como especialista, não tinha absolutamente nenhum direito de escrever esse código.
let node
node = exampleObject.node
Este código resolve o problema. Funciona, está claro o que está sendo feito nele, e meus colegas vão entender sem olhar para lugar nenhum. Quanto à sintaxe destrutiva, não devo usá-la apenas porque posso .
Código não é tudo
Como vimos, a decisão do Expert-2 raramente é questionada se procedemos apenas a partir do código; no entanto, é fácil discernir qual código cada especialista deve escrever. A questão é que as máquinas devem ler o código e as pessoas devem interpretá-lo. Portanto, você precisa considerar fatores que não estão apenas relacionados ao código!
Trabalhar em uma equipe de desenvolvimento de JavaScript terá uma abordagem diferente para a seleção de código do que trabalhar em uma equipe multilíngue, cujos membros estão menos imersos em sutilezas linguísticas.
Vamos comparar o operador de expansão e concat () como exemplo.
O operador de propagação foi adicionado ao ECMAScript há alguns anos e agora é muito comum. Este é um tipo de sintaxe auxiliar com a qual você pode fazer muitas coisas. Em particular, concatene várias matrizes.
const arr1 = [1, 2, 3];
const arr2 = [9, 11, 13];
const nums = [...arr1, ...arr2];
Com todo o potencial do operador de extensão, seu símbolo não é evidente. Portanto, se você não sabe o que ele faz, não o ajudará muito. Embora ambos os especialistas possam calcular que a equipe de profissionais de JavaScript está familiarizada com a sintaxe, o especialista-2, talvez, pense ser possível dizer o mesmo sobre a equipe multilíngue de programadores. Portanto, o Expert-2 pode preferir o método concat (), pois é um verbo informativo que provavelmente pode ser entendido a partir do contexto do código.
Este trecho de código fornece o mesmo resultado numérico que o exemplo acima com o operador de ramal.
const arr1 = [1, 2, 3];
const arr2 = [9, 11, 13];
const nums = arr1.concat(arr2);
Este é apenas um exemplo para mostrar como os fatores humanos afetam a seleção de código. A base de código à qual pessoas de diferentes equipes têm acesso pode ser regida por padrões mais rígidos que não necessariamente acompanham todas as inovações sintáticas interessantes. Então você tem que desviar do código-fonte principal e levar em consideração outros fatores relacionados ao seu kit de ferramentas que podem complicar ou tornar a vida mais fácil para as pessoas que trabalham neste código. Existe um código que pode ser estruturado para ser difícil de testar . Há um código que o deixará encurralado e não será possível aumentar a escala ou adicionar novos recursos . Existe um código onde o desempenho é prejudicado, nem todos os navegadores são compatíveis ou têm acessibilidade insuficiente . O Expert-2 leva em consideração todos esses fatores em suas recomendações.
O Expert-2 também leva em consideração o fator de nomenclatura. Mas sejamos honestos, mesmo os especialistas, na maioria dos casos, não lidam com a nomenclatura.
Conclusão
O verdadeiro especialista não é alguém que aplica todas as exigências da especificação, mas alguém que conhece a especificação bem o suficiente para implantar a sintaxe de maneira racional e tomar decisões bem pensadas. Um especialista que atinge esse nível pode preparar novos especialistas.
O que isso significa para aqueles de nós que se consideram um especialista ou pelo menos aspiram a se tornar um especialista? Isso significa que há muitas perguntas a se fazer quando você escreve um código. Avalie adequadamente os desenvolvedores que são seu público-alvo. O melhor código que você pode escrever é o código que resolve alguns problemas complexos, mas é, por definição, compreensível para aqueles que irão ler sua base de código.
Sim, é muito difícil. E geralmente não há uma resposta única. Mas você deve estar pensando sobre o que precede ao escrever cada uma de suas funções.
Nossas máquinas virtuais podem ser usadas para desenvolvimento Javascript especializado.
Cadastre-se pelo link acima ou clicando no banner e ganhe 10% de desconto no primeiro mês de aluguel de um servidor de qualquer configuração!