Node.js rapidamente se tornou um padrão para a construção de aplicativos da web e software de sistemas, graças à sua capacidade de aproveitar o JavaScript no back-end. Frameworks populares como Express e ferramentas como Webpack contribuem para seu uso generalizado. Embora existam concorrentes como Deno e Bun, o Node continua sendo a principal plataforma JavaScript do lado do servidor.
A natureza multiparadigma do JavaScript permite vários estilos de programação, mas também apresenta riscos como escopo e mutação de objeto. A falta de otimização de chamada final torna perigosas grandes iterações recursivas, e a arquitetura de thread único do Node requer código assíncrono para eficiência. Apesar dos desafios, seguir os principais conceitos e práticas recomendadas em JavaScript pode ajudar os desenvolvedores de Node.js a escrever código escalonável e eficiente.
1. Fechamentos de JavaScript
Um fechamento em JavaScript é uma função interna que tem acesso ao escopo de sua função externa, mesmo depois que a função externa retornou o controle. Um encerramento torna as variáveis da função interna privadas. A programação funcional explodiu em popularidade, tornando os encerramentos uma parte essencial do kit do desenvolvedor Node. Aqui está um exemplo simples de encerramento em JavaScript:
2. Protótipos JavaScript
Toda função JavaScript possui uma propriedade de protótipo que é usada para anexar propriedades e métodos. Esta propriedade não é enumerável. Ele permite ao desenvolvedor anexar métodos ou funções-membro aos seus objetos. JavaScript suporta herança apenas por meio da propriedade protótipo. No caso de um objeto herdado, a propriedade protótipo aponta para o pai do objeto. Uma abordagem comum para anexar métodos a uma função é usar protótipos como mostrado aqui:
Embora o JavaScript moderno tenha suporte de classe bastante sofisticado, ele ainda usa o sistema de protótipo nos bastidores. Esta é a fonte de grande parte da flexibilidade da linguagem.
3. Definindo propriedades privadas usando nomes hash
Antigamente, a convenção de prefixar variáveis com um sublinhado era usada para indicar que uma variável deveria ser privada. No entanto, esta foi apenas uma sugestão e não uma restrição imposta pela plataforma. JavaScript moderno oferece membros e métodos privados de hashtag para aulas:
Nomes de hash privados são um recurso mais recente e muito bem-vindo em JavaScript! Versões e navegadores recentes do Node suportam isso, e as ferramentas de desenvolvimento do Chrome permitem que você acesse diretamente variáveis privadas como uma conveniência.
4. Definindo propriedades privadas usando fechamentos
Outra abordagem que você verá às vezes para contornar a falta de propriedades privadas no sistema protótipo do JavaScript é usar um encerramento. O JavaScript moderno permite definir propriedades privadas usando o prefixo hashtag, conforme mostrado no exemplo acima. No entanto, isso não funciona para o sistema de protótipo JavaScript. Além disso, esse é um truque que você encontrará frequentemente no código e é importante entender o que ele está fazendo.
Definir propriedades privadas usando fechamentos permite simular uma variável privada. As funções-membro que precisam de acesso às propriedades privadas devem ser definidas no próprio objeto. Aqui está a sintaxe para criar propriedades privadas usando encerramentos:
5. Módulos JavaScript
Era uma vez, o JavaScript não tinha sistema de módulos, e os desenvolvedores criaram um truque inteligente (chamado de padrão de módulo) para criar algo que funcionasse. À medida que o JavaScript evoluiu, ele gerou não um, mas dois sistemas de módulos: a sintaxe CommonJS include e a sintaxe ES6 require.
O Node tradicionalmente usa CommonJS, enquanto os navegadores usam ES6. No entanto, versões recentes do Node (nos últimos anos) também suportaram ES6. A tendência agora é usar módulos ES6, e algum dia teremos apenas uma sintaxe de módulo para usar em JavaScript. ES6 se parece com isso (onde exportamos um módulo padrão e depois o importamos):
Você ainda verá o CommonJS e às vezes precisará usá-lo para importar um módulo. Veja como é exportar e importar um módulo padrão usando CommonJS:
6. Tratamento de erros
Não importa em qual idioma ou ambiente você esteja, o tratamento de erros é essencial e inevitável. O nó não é exceção. Existem três maneiras básicas de lidar com erros: blocos try/catch, lançamento de novos erros e manipuladores on().
Blocos com try/catch são os meios testados e comprovados para capturar erros quando algo dá errado:
Nesse caso, registramos o erro no console com console.error. Você pode optar por lançar o erro, passando-o para o próximo manipulador. Observe que isso interrompe a execução do fluxo de código; ou seja, a execução atual é interrompida e o próximo manipulador de erros na pilha assume o controle:
O JavaScript moderno oferece algumas propriedades úteis em seus objetos Error, incluindo Error.stack para dar uma olhada no rastreamento de pilha. No exemplo acima, estamos definindo a propriedade Error.message e Error.cause com os argumentos do construtor.
Outro lugar onde você encontrará erros é em blocos de código assíncronos, onde você lida com resultados normais com .then(). Nesse caso, você pode usar um manipulador on(‘error’) ou um evento onerror, dependendo de como a promessa retorna os erros. Às vezes, a API retornará um objeto de erro como um segundo valor de retorno com o valor normal. (Se você usar await na chamada assíncrona, poderá envolvê-la em um try/catch para lidar com quaisquer erros.) Aqui está um exemplo simples de como lidar com um erro assíncrono:
Não importa o que aconteça, nunca engula erros! Não vou mostrar isso aqui porque alguém pode copiar e colar. Basicamente, se você detectar um erro e não fizer nada, seu programa continuará operando silenciosamente, sem qualquer indicação óbvia de que algo deu errado. A lógica será quebrada e você ficará pensando até encontrar seu bloco catch sem nada nele. (Observe que fornecer um bloco finally{} sem um bloco catch fará com que seus erros sejam engolidos.)
7. Curry JavaScript
Currying é um método de tornar as funções mais flexíveis. Com uma função curried, você pode passar todos os argumentos que a função está esperando e obter o resultado, ou pode passar apenas um subconjunto de argumentos e receber de volta uma função que aguarda o restante dos argumentos. Aqui está um exemplo simples de curry:
A função curried original pode ser chamada diretamente, passando cada um dos parâmetros em um conjunto separado de parênteses, um após o outro:
Esta é uma técnica interessante que permite criar fábricas de funções, onde as funções externas permitem configurar parcialmente a interna. Por exemplo, você também pode usar a função curry acima assim:
No uso no mundo real, essa ideia pode ser uma ajuda quando você precisa criar muitas funções que variam de acordo com determinados parâmetros.
8. Métodos de aplicação, chamada e vinculação de JavaScript
Embora não seja todos os dias que os usamos, é bom entender o que são os métodos call, apply e bind. Aqui, estamos lidando com alguma flexibilidade linguística séria. Basicamente, esses métodos permitem que você especifique o que a palavra-chave this resolve.
Em todas as três funções, o primeiro argumento é sempre o este valor, ou contexto, que você deseja fornecer à função.
Dos três, ligar é o mais fácil. É o mesmo que invocar uma função especificando seu contexto. Aqui está um exemplo:
Observe que apply é quase o mesmo que call. A única diferença é que você passa os argumentos como um array e não separadamente. Arrays são mais fáceis de manipular em JavaScript, abrindo um número maior de possibilidades para trabalhar com funções. Aqui está um exemplo usando apply e call:
O método bind permite que você passe argumentos para uma função sem invocá-la. Uma nova função é retornada com argumentos delimitados antes de quaisquer argumentos adicionais. Aqui está um exemplo:
9. Memoização de JavaScript
Memoização é uma técnica de otimização que acelera a execução de funções, armazenando resultados de operações caras e retornando os resultados armazenados em cache quando o mesmo conjunto de entradas ocorrer novamente. Os objetos JavaScript se comportam como matrizes associativas, facilitando a implementação da memoização em JavaScript. Veja como converter uma função fatorial recursiva em uma função fatorial memorizada:
10. JavaScript IIFE
Uma expressão de função invocada imediatamente (IIFE) é uma função que é executada assim que é criada. Não tem conexão com nenhum evento ou execução assíncrona. Você pode definir um IIFE conforme mostrado aqui:
O primeiro par de parênteses function(){...} converte o código dentro dos parênteses em uma expressão.O segundo par de parênteses chama a função resultante da expressão. Um IIFE também pode ser descrito como uma função anônima autoinvocável. Seu uso mais comum é limitar o escopo de uma variável feita via var ou encapsular o contexto para evitar colisões de nomes.
Também há situações em que você precisa chamar uma função usando await, mas você não está dentro de um bloco de função assíncrona. Isso às vezes acontece em arquivos que você deseja que sejam executáveis diretamente e também importados como um módulo. Você pode agrupar essa chamada de função em um bloco IIFE assim:
11. Recursos úteis de argumento
Embora o JavaScript não suporte sobrecarga de métodos (porque pode lidar com contagens arbitrárias de argumentos em funções), ele possui vários recursos poderosos para lidar com argumentos. Por um lado, você pode definir uma função ou método com valores padrão:
Você também pode aceitar e tratar todos os argumentos de uma vez, para poder lidar com qualquer número de argumentos passados. Isso usa o operador rest para coletar todos os argumentos em uma matriz:
Se você realmente precisa lidar com diferentes configurações de argumentos, você sempre pode verificá-los:
Além disso, lembre-se de que o JavaScript inclui um array de argumentos integrado. Cada função ou método fornece automaticamente a variável argumentos, contendo todos os argumentos passados para a chamada.
Conclusão
Ao se familiarizar com o Node, você perceberá que há muitas maneiras de resolver quase todos os problemas. A abordagem certa nem sempre é óbvia. Às vezes, existem várias abordagens válidas para uma determinada situação. Conhecer as diversas opções disponíveis ajuda.
Os 10 conceitos de JavaScript discutidos aqui são básicos que todo desenvolvedor Node se beneficiará em saber. Mas eles são a ponta do iceberg. JavaScript é uma linguagem poderosa e complexa. Quanto mais você usá-lo, mais entenderá o quão vasto o JavaScript realmente é e o quanto você pode fazer com ele.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3