Bien débuter en Javascript
Comme beaucoup de développeurs tu t’es surement jeté sur Javascript sans trop savoir par où commencer. Pourtant il y a des choses simples à savoir pour bien débuter en Javascript. Je pars du principe que tu joues depuis peu avec Javascript et que tu es là pour en savoir plus. Aujourd’hui, on va voir comment éviter les pièges et ce qui va vraiment t’aider à débuter en Javascript.
Base obligatoire
Avant même de commencer, il te faut la base. Les développeurs qui font du grand n’importe quoi avec Javascript sont ceux qui n’ont pas pris le temps de comprendre comment ça marche. Le problème avec Javascript c’est que c’est tellement facile d’accès que personne se pose la question de pourquoi ou comment ça marche. Pourtant en cinq minutes tu peux tout comprendre avec cet article sublime. Pour bien débuter avec Javascript tu dois savoir comment ça marche. Si tu sais pas ce qu’est le single thread, l’event loop, la callback queue ou le moteur Javascript, tu vas pleurer du sang et c’est pas agréable pour travailler.
Également je vois beaucoup de gens en 2019 ne pas utiliser les dernières spécifications ECMAScript en utilisant Javascript. Je vois encore beaucoup de callback, d’utilisation de mot-clef var, aucun spread operator, aucune arrow fonction bref des gens bloqués en 1999. Stop, on se met à jour. Pour bien débuter avec Javascript tu dois utiliser ces dernières spécifications. Utiliser une var en 2019 ça devrait être puni de 4 ans de prison ferme. Aller je te fais un exemple de code en mode express pour te montrer un peu d’ES6 :
'use strict' const fetch = require('node-fetch') const secretPokemon = ['mew', 'mewtwo'] const favoritePokemonNames = ['charmander', 'pikachu', 'eevee', ...secretPokemon] async function getInfoOnFavoritePokemon () { const allPokemon = await fetch('https://pokeapi.co/api/v2/pokemon?limit=-1').then(response => response.json()) const favoritePokemon = allPokemon.results.filter(pokemon => favoritePokemonNames.includes(pokemon.name)) console.log(favoritePokemon) } getInfoOnFavoritePokemon()
Également il est super important que tu comprennes certaines particularités de Javascript. Pour bien débuter avec Javascript tu dois comprendre certaines bizarreries du langage. Et là je pense aux variables passées en valeur et en référence, l’auto-boxing ou encore l’hosting (version simplifié du process des environnements lexicaux) qui devrait jamais t’arriver si tu n’utilises pas des vars. Cet article est un excellent résumé et je te le conseille fortement.
Bloquant / non bloquant
Maintenant que t’as la base et que tu sais à peu près ce qu’il se passe dans ton Javascript on peut aborder le sujet des opérations bloquantes et non bloquantes. C’est central dans une application Javascript. Javascript est un langage single thread il a donc été pensé dans une philosophie non bloquante. Pour bien débuter avec Javascript tu dois toujours penser à ne jamais bloquer l’event loop. Beaucoup de développeurs n’en ont absolument rien à foutre de ça. Et ça se voit énormément dans la performance et la stabilité de leurs applications. Exemple de code synchrone qui bloque tout.
'use strict' const fs = require('fs') // tant que ce gros fichier n'est pas lu entier ton app est bloqué const hugeJsonFileRaw = fs.readFileSync('./hugeJsonFile.json', 'utf-8') // stringify est également une opération bloquante const data = JSON.stringify(hugeJsonFileRaw) // un while qui compte jusqu'à 10 milliards pour bien prendre tout le CPU let increment = 0 while (increment !== Math.pow(10, 10)) { increment++ } console.log('Tu vas attendre longtemps avant de voir ce message.')
Il te faut toujours adopter une approche asynchrone dans tout ce qu’on te demande. Par exemple, tu peux utiliser la version asynchrone de readFile. Elle utilise un callback et c’est moche. À la place tu peux promisify cette callback et du coup utiliser les promesses. Ou encore mieux : tu peux abstraire tout ça dans une fonction et utiliser un async / await pour gérer le tout de manière plus élégante.
'use strict' const fs = require('fs') const readFile = require('util').promisify(fs.readFile) const pathToFile = './hugeJsonFile.json' const readMyFile = async path => { const data = await readFile(path, 'utf-8') return data } readMyFile(pathToFile).then(data => console.log(data)) console.log('Tu vois ce message tout de suite.')
En ce qui concerne les opérations coûteuses en CPU comme le while il existe aussi des solutions asynchrones. Par exemple les workers threads qui sont très efficaces dans ce scénario, mais c’est un sujet un peu plus avancé. Également je te conseille de toujours penser à la performance de chacune des commandes que tu fais. On a tendance à l’oublier, mais une commande non optimisée peut bouffer du CPU et bloquer l’event loop. Par exemple si tu as le choix entre utiliser plusieurs types loop choisis le for quand ça fait du sens. C’est dans la plupart des cas la solution la plus rapide.
Fonction d’ordre supérieur et programmation fonctionnelle
Maintenant que tu as la base et que tu bloques plus ton app il est temps de traiter de la donnée. Ça va être ta principale activité de traiter de la donnée donc autant faire ça bien. Javascript est un langage fonctionnel. Pour bien débuter en javascript il est important de maîtriser les fonctions d’ordre supérieur. Une fonction d’ordre supérieur est simplement une fonction qui prend en paramètre une autre fonction. Et ce détail va nous permettre de simplifier grandement les choses. Pour mieux comprendre, jetons un coup d’œil au code.
'use strict' const pokemons = [ { name: 'newtwo', type: 'psychic', isFavorite: true }, { name: 'pikachu', type: 'electric', isFavorite: true }, { name: 'nidorino', type: 'poison', isFavorite: false } ] // récupérer mes pokemons préférés dans un tableau sans fonction d'ordre supérieur const favoritePokemonsWithFor = [] for (let i = 0; i < pokemons.length; i++) { if (pokemons[i].isFavorite) { favoritePokemonsWithFor.push(pokemons[i]) } } console.log(favoritePokemonsWithFor) // même chose avec fonction d'ordre supérieur const favoritePokemonsWithFilter = pokemons.filter(pokemon => pokemon.isFavorite) console.log(favoritePokemonsWithFilter)
Concrètement la fonction filter accepte une autre fonction qui prend pour premier argument l’élément courant du tableau. Une valeur de retour est retournée seulement si la condition (pokemon.isFavorite) est positive. En une ligne, on fait exactement la même chose que le for au-dessus. Mais on le fait de façon plus concise, moins compliquée et plus modulable. Car oui, on peut très bien extraire la logique de la fonction de condition pour autre chose. Et on peut aussi chaîner les fonctions d’ordre supérieur.
'use strict' const pokemons = [ { name: 'newtwo', type: 'psychic', isFavorite: true }, { name: 'pikachu', type: 'electric', isFavorite: true }, { name: 'nidorino', type: 'poison', isFavorite: false } ] const isMyFavoritePokemon = pokemon => pokemon.isFavorite const myPokemonNames = pokemons.filter(isMyFavoritePokemon).map(pokemon => pokemon.name) console.log(myPokemonNames)
En appliquant ce principe à tous tes traitements de données tu feras du code plus rapidement, plus lisible, plus facile à maintenir et donc de meilleure qualité. Et s’il y a bien une fonction d’ordre supérieur que j’utilise tout le temps c’est reduce. Quand j’ai compris comment bien utiliser Reduce je l’ai utilisé partout, tout le temps. À l’époque c’est cette vidéo qui m’avait fait adopter reduce. Ça a changé beaucoup de choses dans ma façon de faire et je te conseille très fortement d’y jeter un œil.
Programmation orientée objet à prototype
Depuis le début, je te parle seulement de programmation fonctionnelle. Et c’est en effet une partie très importante de Javascript. Mais tu vas tomber nez à nez avec beaucoup de code Javascript orienté objet. Et il faut que tu sois à l’aise avec. Surtout que la programmation orientée objet côté Javascript n’est pas tout à fait de la programmation-objet. Il s’agit de programmation orienté objet à prototype. Et malgré le sucre syntaxique des classes ES6, pour bien débuter en Javascript il faut que tu comprennes comment les prototypes fonctionnent.
C’est un vaste sujet, y’a beaucoup de choses à voir là-dessus. Le plus important à comprendre c’est qu’en Javascript tout est un objet. Tous les objets héritent d’un prototype, qui est lui-même un objet, qui embarque des méthodes utilisables dans le premier objet. Et tout ça implique BEAUCOUP d’autres choses ! Ça mérite un article dédié. Je te conseille fortement la lecture de cet article qui est le résumé le plus clair et concis que j’ai pu trouver. C’est vraiment quelque chose qui va t’éviter pas mal d’incompréhension si tu le maîtrises donc ne fais pas l’impasse.
Les librairies
Tu le sais, on te l’a dit 100 fois de pas réinventer la roue. De pas refaire des solutions déjà existantes. Javascript est tellement populaire que tout, ou presque tout, a déjà une solution. Pour bien débuter en Javascript il faut que tu connaisses les librairies les plus utiles. Par exemple, une librairie que j’utilise presque tout le temps est Lodash. Lodash me résout énormément de complexité avec la manipulation de données et l’itération. Je peux me concentrer sur mes features pendant que Lodash fait la job pour moi. C’est vraiment une des meilleures librairies multitâches et je te conseille vraiment de l’intégrer.
Y’a pas que Lodash dans la vie. Une autre librairie que j’utilise tout le temps est Joi. Très puissant pour valider les paramètres d’entrés d’API ou n’importe quelle autre data de façon élégante. Si tu dois bosser avec des dates et que ça commence à être complexe, je te conseille fortement Moment.js. Pareil. C’est une solution élégante et puissante. Je vais pas tous te les faire, mais prends le soin de vérifier qu’une solution n’existe pas avant de réinventer la roue.
Linter et plugin IDE
Le Javascript est très permissif dans son utilisation. Ça veut dire que tu peux vite coder comme un gros porc et ça marche. Tu veux pas ça. Il faut que tu t’imposes des règles et une façon de faire. Sinon ton code, ça va être carnaval. Pour bien débuter en Javascript tu dois choisir un guide de style et t’y maintenir. Moi j’utilise StandardJS. Ça veut pas dire que tu dois utiliser le même.
Je vais être franc avec toi : je m’en fous de celui que tu vas choisir. Les débats religieux ne m’intéressent pas. Mais choisis-en un et utilise-le partout. Un guide de style va te permettre une constance dans ta manière de travailler en Javascript. Tu seras jamais perdu sur la façon de faire. C’est un must !
Et l’avantage avec un guide de style c’est que tu peux utiliser un linter pour formater automatiquement ton code. Tu peux le faire en installant directement le linter en ligne de commande via un npm install. Mais tu peux le faire aussi directement via ton IDE. Peu importe l’IDE que tu utilises, tu trouveras un plugin de linter pour les principaux guides de style. Ça te permettra d’avoir une qualité de code de façon automatique et intégrée à ton environnement de travail. Et ça, c’est la vie.
Épilogue
Déjà si t’arrives à intégrer tout ça au début de ton apprentissage Javascript c’est beaucoup. Tu vas être à l’aise pour la suite. Tu te doutes bien que Javascript a encore beaucoup de choses sous le capot. Mais c’est pas le sujet de l’article d’aujourd’hui. Dans le futur je ferai un article intermédiaire et un autre plus avancé. En attendant, je te conseille la lecture de ce bouquin si tu veux aller plus loin. C’est le bouquin qui m’a fait le plus évoluer en Javascript et je suis pas le seul.
Top article comme d’habitude.
Concernant MomentJS, je l’ai récemment changé avec date-fns notamment pour des raisons de poids ! 🙂
C’est bien beau tout ça, mais faudrait préciser que ce serait mieux uniquement sous NodeJS, parce que exemple tout con, utiliser la fonction « includes » sous IE, bonne chance ! Pour rappel IE s’arrête a ECMAScript 5 … 2009 ! Et ES6 c’est 2015, un gouffre dans le monde professionnel.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes
Bref, l’article est très mal orienté dans son titre !
En effet j’ai oublié de préciser que j’utilise NodeJS 12.13.0
Merci pour ton commentaire.
Mais bon, pour le côté front y’a ça (par exemple) : https://babeljs.io/
Je rajouterai que l’usage de « use strict » (fonctionnalité ES5) n’est plus d’actualité si on utilise les modules ES6 qui sont par défaut en « strict ». C’est l’approche « one js ». Plus d’info ici : https://exploringjs.com/es6/ch_one-javascript.html#sec_strict-mode-and-es6. Bon après, vu que t’es en Nodejs et que les modules ES6 ne sont pas encore très fréquemment utilisés (sauf avec babel ou autre) je comprends pourquoi tu l’as mis…
IE n’existe plus, on est passé à Edge maintenant.
S’il y a des clients ou des éditeurs qui demandent encore une compatibilité IE, ceux-ci sont de plus en plus rares. Pour ma part, je n’ai pas à me soucier d’IE, et je fais du JS pour le front.
Haaa, merci Mehdi. Pour un dev plutôt back mais qui bosse en one-man-army (ou presque), cet article va servir de base saine pour reprendre ces concepts et les bosser comme il faut, ENFIN. Vraiment, merci !
Yo !
Pour beaucoup de choses, si on commence à adopter une approche fonctionnelle, je conseille très fortement Ramda qui permet de se faciliter la vie et apporte de très nombreuses méthodes similaires à Loadash mais plus adaptées à la prog fonctionnelle.
Il y a mille et un modules utiles, perso je m’étais fais une petite liste des modules que j’utilise souvent :
https://buzut.net/modules-javascript-indispensables/
La « simple » commande npm et son package.json méritent à eux seuls un article entier.
Certains disent que le node_modules est l’enfer sur disque dur, mais à mon humble avis, c’est un des meilleurs package manager du moment.
Bref, connaître node.js sans npm, c’est se couper 50% des possibilités.
Un autre outil dont je ne peux plus me passer est « prettier » avec « husky », ton code remis d’équerre les yeux fermés à chaque commit. Tu peux même reformater tes json, yaml et markdown.
Je pense aussi que l’utilisation de typescript te fais gagner du temps sur un développement long, quand tu oublies que telle classe est utilisée à 36 endroits etc.
Et btw: « const fs = require(‘fs’).promises » depuis la v10.0.0 je pense.
Bonjour !!
Je me considère encore comme un débutant en JS (J’avais un prof qui été encore à la préhistoire niveau JS Exemple : Non utilisation des addEventListener). Auriez-vous un cours / livres à jour vis à vis des normes actuel JS pour apprendre correctement && proprement le JS. Merci d’avance. Vous pouvez répondre ici, je regarderais les réponses ^^ .