Node.js est rapidement devenu un standard pour la création d'applications Web et de logiciels système, grâce à sa capacité à exploiter JavaScript sur le back-end. Des frameworks populaires comme Express et des outils comme Webpack contribuent à son utilisation généralisée. Bien que des concurrents comme Deno et Bun existent, Node reste la principale plate-forme JavaScript côté serveur.
La nature multiparadigme de JavaScript permet différents styles de programmation, mais elle présente également des risques tels que la portée et la mutation des objets. Le manque d’optimisation des appels finals rend dangereuses les grandes itérations récursives, et l’architecture monothread de Node nécessite du code asynchrone pour plus d’efficacité. Malgré les défis, suivre les concepts clés et les meilleures pratiques en JavaScript peut aider les développeurs Node.js à écrire du code évolutif et efficace.
1. Fermetures JavaScript
Une fermeture en JavaScript est une fonction interne qui a accès à la portée de sa fonction externe, même après que la fonction externe a rendu le contrôle. Une fermeture rend les variables de la fonction interne privées. La programmation fonctionnelle a explosé en popularité, faisant des fermetures un élément essentiel du kit du développeur Node. Voici un exemple simple de fermeture en JavaScript :
2. Prototypes JavaScript
Chaque fonction JavaScript possède une propriété prototype utilisée pour attacher des propriétés et des méthodes. Cette propriété n'est pas énumérable. Il permet au développeur d'attacher des méthodes ou des fonctions membres à ses objets. JavaScript prend en charge l'héritage uniquement via la propriété prototype. Dans le cas d'un objet hérité, la propriété prototype pointe vers le parent de l'objet. Une approche courante pour attacher des méthodes à une fonction consiste à utiliser des prototypes comme indiqué ici :
Bien que le JavaScript moderne ait un support de classe assez sophistiqué, il utilise toujours le système prototype sous le capot. C’est la source d’une grande partie de la flexibilité du langage.
3. Définir des propriétés privées à l'aide de noms de hachage
Auparavant, la convention consistant à préfixer les variables avec un trait de soulignement était utilisée pour indiquer qu'une variable était censée être privée. Cependant, il ne s’agissait que d’une suggestion et non d’une restriction imposée par la plateforme. JavaScript moderne propose des membres privés de hashtag et des méthodes pour les cours :
Les noms de hachage privés sont une fonctionnalité plus récente et très bienvenue en JavaScript ! Les versions récentes de Node et les navigateurs le prennent en charge, et les outils de développement Chrome vous permettent d'accéder directement aux variables privées pour plus de commodité.
4. Définir des propriétés privées à l'aide de fermetures
Une autre approche que vous verrez parfois pour contourner le manque de propriétés privées dans le système prototype de JavaScript consiste à utiliser une fermeture. Le JavaScript moderne vous permet de définir des propriétés privées en utilisant le préfixe hashtag, comme le montre l'exemple ci-dessus. Cependant, cela ne fonctionne pas pour le système prototype JavaScript. De plus, c'est une astuce que vous trouverez souvent dans le code et il est important de comprendre ce qu'elle fait.
La définition de propriétés privées à l'aide de fermetures vous permet de simuler une variable privée. Les fonctions membres qui ont besoin d'accéder aux propriétés privées doivent être définies sur l'objet lui-même. Voici la syntaxe pour créer des propriétés privées à l'aide de fermetures :
5. Modules JavaScript
Il était une fois, JavaScript n'avait pas de système de modules, et les développeurs ont conçu une astuce intelligente (appelée modèle de module) pour créer quelque chose qui fonctionnerait. Au fur et à mesure de l'évolution de JavaScript, il a engendré non pas un mais deux systèmes de modules : la syntaxe CommonJS include et la syntaxe ES6 require.
Node utilise traditionnellement CommonJS, tandis que les navigateurs utilisent ES6. Cependant, les versions récentes de Node (au cours des dernières années) prennent également en charge ES6. La tendance est désormais à l’utilisation de modules ES6, et un jour nous n’aurons qu’une seule syntaxe de module à utiliser dans JavaScript. ES6 ressemble à ceci (où nous exportons un module par défaut puis l'importons) :
Vous verrez toujours CommonJS et vous devrez parfois l'utiliser pour importer un module. Voici à quoi cela ressemble pour exporter puis importer un module par défaut à l'aide de CommonJS :
6. Gestion des erreurs
Quel que soit la langue ou l'environnement dans lequel vous vous trouvez, la gestion des erreurs est essentielle et inévitable. Le nœud ne fait pas exception. Il existe trois manières de base de gérer les erreurs : les blocs try/catch, le lancement de nouvelles erreurs et les gestionnaires on().
Les blocs avec try/catch sont le moyen éprouvé pour capturer les erreurs lorsque les choses tournent mal :
Dans ce cas, nous enregistrons l'erreur sur la console avec console.error. Vous pouvez choisir de renvoyer l'erreur, en la transmettant au gestionnaire suivant. Notez que cela interrompt l'exécution du flux de code ; c'est-à-dire que l'exécution en cours s'arrête et que le gestionnaire d'erreurs suivant dans la pile prend le relais :
JavaScript moderne offre de nombreuses propriétés utiles sur ses objets Error, notamment Error.stack pour consulter la trace de la pile. Dans l'exemple ci-dessus, nous définissons la propriété Error.message et Error.cause avec les arguments du constructeur.
Vous trouverez également des erreurs dans les blocs de code asynchrones où vous gérez les résultats normaux avec .then(). Dans ce cas, vous pouvez utiliser un gestionnaire on('error') ou un événement onerror, selon la manière dont la promesse renvoie les erreurs. Parfois, l'API vous renvoie un objet d'erreur comme deuxième valeur de retour avec la valeur normale. (Si vous utilisez wait sur l'appel asynchrone, vous pouvez l'envelopper dans un try/catch pour gérer les erreurs.) Voici un exemple simple de gestion d'une erreur asynchrone :
Quoi qu’il en soit, n’avalez jamais les erreurs ! Je ne le montrerai pas ici car quelqu’un pourrait le copier et le coller. Fondamentalement, si vous détectez une erreur et ne faites rien, votre programme continuera à fonctionner silencieusement sans aucune indication évidente que quelque chose s'est mal passé. La logique sera brisée et vous devrez réfléchir jusqu'à ce que vous trouviez votre bloc catch sans rien dedans. (Notez que fournir un bloc finally{} sans bloc catch entraînera l'absorption de vos erreurs.)
7. Currying JavaScript
Le currying est une méthode permettant de rendre les fonctions plus flexibles. Avec une fonction au curry, vous pouvez transmettre tous les arguments attendus par la fonction et obtenir le résultat, ou vous pouvez transmettre uniquement un sous-ensemble d'arguments et recevoir en retour une fonction qui attend le reste des arguments. Voici un exemple simple de curry :
La fonction curry originale peut être appelée directement en passant chacun des paramètres dans un ensemble distinct de parenthèses, l'un après l'autre :
C'est une technique intéressante qui vous permet de créer des usines de fonctions, où les fonctions externes vous permettent de configurer partiellement la fonction interne. Par exemple, vous pouvez également utiliser la fonction curry ci-dessus comme ceci :
Dans le monde réel, cette idée peut être utile lorsque vous devez créer de nombreuses fonctions qui varient en fonction de certains paramètres.
8. Méthodes JavaScript d'application, d'appel et de liaison
Même si nous ne les utilisons pas tous les jours, il est bon de comprendre ce que sont les méthodes call, apply et bind. Ici, nous avons affaire à une certaine flexibilité linguistique sérieuse. Au fond, ces méthodes vous permettent de spécifier à quoi le mot-clé this résout.
Dans les trois fonctions, le premier argument est toujours la cette valeur, ou contexte, que vous souhaitez attribuer à la fonction.
Des trois, appeler est le plus simple. C’est la même chose que d’invoquer une fonction tout en spécifiant son contexte. Voici un exemple :
Notez que appliquer est presque identique à appeler. La seule différence est que vous transmettez les arguments sous forme de tableau et non séparément. Les tableaux sont plus faciles à manipuler en JavaScript, ouvrant un plus grand nombre de possibilités pour travailler avec des fonctions. Voici un exemple utilisant apply et call :
La méthode bind vous permet de transmettre des arguments à une fonction sans l'invoquer. Une nouvelle fonction est renvoyée avec des arguments délimités précédant tout autre argument. Voici un exemple :
9. Mémorisation JavaScript
La mémoisation est une technique d'optimisation qui accélère l'exécution des fonctions en stockant les résultats d'opérations coûteuses et en renvoyant les résultats mis en cache lorsque le même ensemble d'entrées se reproduit. Les objets JavaScript se comportent comme des tableaux associatifs, ce qui facilite la mise en œuvre de la mémorisation en JavaScript. Voici comment convertir une fonction factorielle récursive en fonction factorielle mémorisée :
10. JavaScript IIFE
Une expression de fonction immédiatement invoquée (IIFE) est une fonction qui est exécutée dès sa création. Il n’a aucun lien avec des événements ou une exécution asynchrone. Vous pouvez définir un IIFE comme indiqué ici :
La première paire de parenthèses function(){...} convertit le code entre parenthèses en une expression. La deuxième paire de parenthèses appelle la fonction résultant de l'expression. Une IIFE peut également être décrite comme une fonction anonyme auto-invoquée. Son utilisation la plus courante est de limiter la portée d'une variable créée via var ou d'encapsuler le contexte pour éviter les collisions de noms.
Il existe également des situations dans lesquelles vous devez appeler une fonction en utilisant await, mais vous n'êtes pas dans un bloc de fonction asynchrone. Cela arrive parfois dans des fichiers que vous souhaitez exécutables directement et également importés en tant que module. Vous pouvez envelopper un tel appel de fonction dans un bloc IIFE comme ceci :
11. Fonctionnalités d'argumentation utiles
Bien que JavaScript ne prenne pas en charge la surcharge de méthodes (car il peut gérer un nombre d'arguments arbitraires sur les fonctions), il dispose de plusieurs fonctionnalités puissantes pour gérer les arguments. D'une part, vous pouvez définir une fonction ou une méthode avec des valeurs par défaut :
Vous pouvez également accepter et gérer tous les arguments en même temps, afin de pouvoir gérer n'importe quel nombre d'arguments transmis. Cela utilise l'opérateur rest pour collecter tous les arguments dans un tableau :
Si vous avez vraiment besoin de gérer différentes configurations d'arguments, vous pouvez toujours les vérifier :
N'oubliez pas non plus que JavaScript inclut un tableau d'arguments intégré. Chaque fonction ou méthode vous donne automatiquement la variable arguments, contenant tous les arguments passés à l'appel.
Conclusion
Au fur et à mesure que vous vous familiariserez avec Node, vous remarquerez qu'il existe de nombreuses façons de résoudre presque tous les problèmes. La bonne approche n’est pas toujours évidente. Parfois, il existe plusieurs approches valables pour une situation donnée. Connaître les nombreuses options disponibles est utile.
Les 10 concepts JavaScript abordés ici sont des bases que tout développeur Node bénéficiera de connaître. Mais ils ne représentent que la pointe de l’iceberg. JavaScript est un langage puissant et complexe. Plus vous l'utiliserez, plus vous comprendrez à quel point JavaScript est vaste et tout ce que vous pouvez en faire.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3