L'introduction à JavaScript la plus honnête, disponible gratuitement en ligne. Mise à jour ES2024.
Pourquoi ce livre
Eloquent JavaScript est en ligne gratuitement depuis 2011. Haverbeke le met à jour à chaque version majeure d'ECMAScript, sans exception : la quatrième édition couvre ES2024. La plupart des livres de programmation prennent la poussière ; celui-là est un document vivant depuis quinze ans.
Mais ce qui le distingue, ce n'est pas le prix ni la mise à jour. C'est le ton. Haverbeke ouvre l'introduction en avouant avoir rapidement détesté JavaScript. Puis, quelques pages plus loin, qu'il a fini par l'aimer. Cette trajectoire, c'est tout le livre : partir d'une confusion honnête, la traverser jusqu'à une vraie compréhension. Il vous montre le binaire, puis l'assembleur, puis le JS. Et vous comprenez pourquoi les langages existent.
Les idées qui restent
1Un programme est une construction de pensée
L'introduction montre le même programme (additionner les entiers de 1 à 10) en binaire brut, puis en pseudo-assembleur lisible, puis en boucle while JavaScript, puis en sum(range(1, 10)). La morale est explicite : « un bon langage de programmation permet au développeur de parler des actions à effectuer à un niveau plus élevé » (p. 8). Ce cadrage, posé tôt et illustré concrètement, répond mieux à la question "pourquoi les langages existent" que beaucoup de cours de CS entiers.
2Les fonctions sont des valeurs : la vraie rupture
Dans la plupart des langages, une fonction est une entité spéciale qu'on ne peut pas manipuler comme une donnée. En JavaScript, ce n'est pas le cas : une fonction se stocke dans une variable, se passe en argument, se retourne depuis une autre fonction. Haverbeke illustre ça en stockant une fonction dans launchMissiles, puis en la réassignant à une no-op selon une condition :
let launchMissiles = () => { /* vrai lancement */ }; if (safeMode) { launchMissiles = () => {}; // remplacée par une no-op } launchMissiles(); // ne fait rien en mode sécurisé
C'est ce mécanisme qui rend possible les callbacks, les fonctions d'ordre supérieur, et les closures des chapitres suivants.
3Les closures : l'environnement voyage avec la fonction
Sans closure, une fonction interne perd ses variables dès que la fonction parente se termine. JavaScript fait le contraire : multiplier(2) retourne une fonction qui multiplie par 2, et cette fonction conserve l'accès à factor = 2 même après la fin de multiplier :
function multiplier(factor) { return number => number * factor; } let double = multiplier(2); double(5); // 10, factor est toujours accessible
« Un bon modèle mental est de penser que les fonctions contiennent à la fois le code de leur corps et l'environnement dans lequel elles ont été créées » (p. 72). Ce mécanisme est derrière :
- les event handlers (ils capturent l'élément DOM ou l'état au moment de leur création) ;
- les factory functions (chaque appel produit une nouvelle fonction avec son propre état privé) ;
- l'application partielle (fixer certains arguments maintenant, fournir le reste plus tard) ;
- une large partie des packages npm (la plupart des librairies utilitaires ne sont que des closures sur une configuration).
4filter, map, reduce : penser par transformations
Le chapitre 5 utilise un dataset de systèmes d'écriture humains (latin, arabe, han...) pour illustrer les fonctions d'ordre supérieur. Haverbeke compare deux recettes de soupe aux pois : l'une liste chaque geste étape par étape ; l'autre dit juste "faire tremper, mijoter, hacher". Même résultat, mais la seconde exige qu'on connaisse le vocabulaire.
En code, c'est pareil : calculer l'âge moyen des alphabets vivants tient en une expression lisible :
SCRIPTS.filter(s => s.living).map(s => s.year)
Sélectionner, transformer, agréger. C'est ce que ça veut dire penser par transformations.
5Les prototypes et le vrai sens de this
Les objets JS sont liés à d'autres objets via une chaîne de prototypes : quand une propriété est absente, le runtime remonte la chaîne jusqu'à la trouver ou atteindre null. Object.getPrototypeOf([]) == Array.prototype vaut true : voilà pourquoi vos tableaux ont .map() sans que vous les ayez définis.
Le chapitre explique aussi pourquoi this dans une arrow function pointe vers le contexte lexical, alors que dans une fonction classique il dépend de l'appelant. C'est la confusion la plus fréquente dans les callbacks JS.
6JavaScript est permissif par conception : avantages et pièges
JS a été conçu pour être tolérant : il exécute du code approximatif sans se plaindre, convertit les types tout seul, et ne plante pas là où d'autres langages lanceraient une erreur. Pratique pour démarrer, piégeux à grande échelle :
compteur = 0 // oubli de "let" : globale créée EN SILENCE
0 == false // true (conversion automatique)
0 === false // false (=== ne convertit pas : à préférer toujours)
"5" - 1 // 4 ("5" devient nombre)
"5" + 1 // "51" (1 devient texte !) : le piège classique
Un NaN (« not a number », le résultat d'une opération invalide comme "abc" * 2) se propage ensuite sans message jusqu'à un affichage faux. Haverbeke nomme ces pièges clairement et présente les parades (le mode strict, === systématique, TypeScript) sans les vendre comme des panacées.
7De callback hell à async/await : l'évolution de l'asynchrone
JS tourne sur un seul thread : il ne peut pas bloquer en attendant une réponse réseau sans figer toute la page. Le chapitre retrace l'histoire complète des solutions :
- Les callbacks : vous passez une fonction à exécuter quand la réponse arrive. Simple, mais imbriquer cinq callbacks pour séquencer cinq opérations produit une pyramide illisible.
- Les Promises : un reçu pour une valeur future. L'imbrication disparaît :
.then().then().catch()s'enchaîne à plat. Les erreurs se propagent automatiquement. - async/await : du sucre syntaxique sur les Promises qui ressemble à du code synchrone.
const data = await fetch(url)semble immédiat ; le moteur gère la Promise dessous.
« Une fonction async peut, dans son corps, attendre d'autres Promises d'une façon qui ressemble à du synchrone » (p. 283). Il faut quand même comprendre les Promises pour déboguer ce qui coince, mais async/await est là où on vit au quotidien.
8Les modules : des LEGO plutôt que de la boue
Avant les ES modules (2015), tout le JavaScript tournait dans une portée globale partagée : deux scripts pouvaient écraser les variables l'un de l'autre sans avertissement. Le module renverse ça : chaque fichier choisit ce qu'il expose et ce qu'il emprunte.
// panier.js : ce fichier décide de ce qui sort, le reste reste privé
export function total(lignes) { ... }
const TVA = 0.2 // invisible dehors : pas de collision possible
// facture.js : on emprunte par son nom, le connecteur bien défini
import { total } from './panier.js'
Haverbeke appelle ça « du LEGO, où les pièces interagissent via des connecteurs bien définis, plutôt que de la boue où tout se mélange » (p. 250) : export et import sont ces connecteurs. npm arrive avec plus de trois millions de packages ; « une bonne partie est de la camelote, pour être honnête » (p. 254). Cette franchise sur l'écosystème est caractéristique du ton du livre.
Trois choses que je ne savais pas avant de le lire
- Haverbeke utilise une corneille nommée Carla pour enseigner la programmation asynchrone. Elle pirate un WiFi par timing attack : tester chaque chiffre du code et mesurer la rapidité du rejet. Tout le chapitre 11 se déroule à travers ce récit absurde : callbacks, Promises et async/await s'enchaînent naturellement dans la même histoire sans rupture.
- En trois pages, Haverbeke montre que
sum(range(1, 10))et sa version en binaire calculent la même chose, mais l'une se lit, l'autre pas. C'est l'argument du livre entier : un langage qui permet de nommer des concepts change ce qu'on peut raisonner dessus. - La licence du livre est Creative Commons. Haverbeke publie gratuitement parce qu'il pense que c'est la bonne chose à faire. Il vend une version papier avec un chapitre bonus pour ceux qui veulent soutenir le travail. Ce modèle a maintenu le livre vivant quinze ans.
Mon avis, honnêtement
Haverbeke a un argument de vente que personne d'autre n'a : il avoue avoir détesté JavaScript avant de l'aimer (p. 9). Il part donc exactement d'où vous partez. Et ses douze premiers chapitres montent dans le bon ordre : fonctions comme valeurs, closures, filter/map/reduce, prototypes. Chaque concept s'appuie sur le précédent, et les exercices ne demandent pas de recopier : ils vous laissent vous débrouiller, et c'est là qu'on apprend.
Les chapitres navigateur (13 à 19) sont corrects mais moins essentiels : si votre but est de comprendre JS, les douze premiers suffisent. Le jeu de plateforme du chapitre 16 est sympa, mais trois chapitres pour un jeu, c'est un investissement. Lecture en diagonale autorisée, je ne le dirai à personne.
En 2026, l'IA génère du JavaScript au kilomètre, et c'est exactement pour ça qu'il faut comprendre les closures et la chaîne de prototypes : c'est ce qui permet de relire ce code et d'y repérer les surprises. React lui-même n'est que des closures bien habillées (les hooks capturent l'état). Et le livre qui explique tout ça est gratuit depuis quinze ans. Il n'y a littéralement pas d'excuse.
Odilon
Toujours valable en 2026 ?
La 4e édition date de 2024 et couvre ES2024 : propriétés privées (#property), optional chaining (obj?.prop), structuredClone, top-level await : tout y est. Les fondamentaux (closures, prototypes, event loop) sont aussi pertinents qu'à la sortie, parce que les frameworks sont construits par-dessus. La seule partie qui vieillit est la section DOM/navigateur : exacte, mais moins représentative du frontend moderne.
Pour qui ?
Lisez-le si
- Vous écrivez du JavaScript mais avez l'impression de deviner pourquoi les closures,
thisou les Promises se comportent ainsi - Vous débutez et voulez un seul livre qui vous emmène du zéro au Node.js, gratuitement
- Vous relisez du JS généré par IA et voulez un cadre solide pour le juger
- Vous aimez les livres qui vous traitent en adulte : pas de simplifications excessives, de vrais exercices
Passez si
- Vous comprenez déjà les closures, la chaîne de prototypes et l'event loop : vous le saurez dès le chapitre 3
- Vous cherchez une référence qu'on consulte par index : la MDN remplit mieux ce rôle
- Vous cherchez React, Vue, ou TypeScript spécifiquement : ce livre ne couvre pas les frameworks ni le JS typé
Pour aller plus loin
Les chapitres sur les closures et les prototypes se pratiquent directement dans le cours JavaScript de ce site. Pour TypeScript (la couche typée au-dessus de JS), Effective TypeScript de Dan Vanderkam est la suite logique. Pour les patterns async en pratique, le cours API REST couvre fetch et async/await dans un contexte réel.
Commentaires (0)