Code review lundi matin. Un dev junior me montre son composant React.
Propre, hooks bien separes, state management correct. Je lui demande
de m'expliquer pourquoi son useEffect a un tableau de dependances vide.
Il hesite. "Pour que ca se lance une seule fois." D'accord, mais pourquoi ?
Qu'est-ce qui se passe si tu mets une dependance dedans ? Silence.
Il ne savait pas. Claude avait ecrit le hook, il avait copie, ca marchait.
Six mois de React et il n'avait jamais ecrit un addEventListener a la main.
JavaScript est le langage le plus copie-colle de la planete. C'etait vrai
avec Stack Overflow, c'est pire avec l'IA. Le langage est partout, front, back,
mobile, serverless, scripts de build, et cette ubiquite cree une illusion :
on croit maitriser JS parce qu'on fait tourner du code JS. Mais si tu ne comprends
pas l'event loop, les closures, le comportement de this ou la difference
entre == et ===, tu construis sur du sable.
Cet article explique comment utiliser Claude pour vraiment apprendre
JavaScript, le langage, pas le framework du moment.
Pourquoi apprendre JavaScript en 2026 malgre l'IA
"L'IA ecrit du JS mieux que moi, pourquoi m'embeter ?" Trois raisons pragmatiques.
1. JavaScript a plus de pieges que n'importe quel autre langage mainstream.
Coercion de types, this qui change selon le contexte d'appel,
hoisting, temporal dead zone, prototypes vs classes. L'IA genere du code
qui evite ces pieges, mais le jour ou tu dois debugger du code legacy
avec des var partout et des callbacks imbriques sur 6 niveaux,
c'est toi qui lis le code, pas Claude.
2. L'ecosysteme bouge plus vite que l'IA ne se met a jour. Nouvelle API du navigateur, nouveau runtime (Bun, Deno), nouveau pattern React : Claude connait la version d'il y a quelques mois. Si tu comprends les fondamentaux, tu t'adaptes. Si tu ne comprends que la reponse de Claude, tu es bloque des que le contexte change.
3. Le front-end est visible. Ton bug Python plante silencieusement
sur un serveur. Ton bug JavaScript casse l'interface devant l'utilisateur,
en production, en temps reel. Le cout d'un TypeError: Cannot read properties
of undefined en production est immediat et visible. Comprendre JS en profondeur
n'est pas un luxe, c'est de la gestion de risque.
Les 5 pieges specifiques a JavaScript
Les anti-patterns generiques de l'apprentissage par IA (copier-coller aveugle, ne jamais ecrire en premier, sauter le debug) s'appliquent. Mais JavaScript a ses pieges bien a lui.
Piege 1 : Confondre == et ===
L'IA utilise toujours ===. C'est bien. Mais si tu ne sais pas
pourquoi, tu ne comprends pas la coercion de types, et tu ne peux
pas lire du code legacy qui utilise == partout.
// Ca a l'air innocent...
console.log(0 == ''); // true
console.log(0 == '0'); // true
console.log('' == '0'); // false, attend, quoi ?
console.log(null == undefined); // true
console.log(null === undefined); // false
// La regle : utilise === partout. Mais comprends POURQUOI.
// == fait de la coercion de types avant comparaison.
// === compare valeur ET type, sans conversion.
Piege 2 : Ne pas comprendre this
this en JavaScript ne fonctionne pas comme dans les autres langages.
Sa valeur depend de comment la fonction est appelee, pas d'ou elle est definie.
L'IA ecrit des arrow functions partout pour eviter le probleme.
Le jour ou tu tombes sur du code avec bind, call,
ou apply, tu es perdu.
const user = {
name: 'Alice',
greet() {
console.log(`Hello, ${this.name}`);
}
};
user.greet(); // "Hello, Alice", ok
const greetFn = user.greet;
greetFn(); // "Hello, undefined", this est perdu
// Arrow function = this lexical (herite du scope parent)
// Methode classique = this depend de l'appel
// Deux regles differentes. Il faut connaitre les deux.
Piege 3 : Utiliser async/await sans comprendre les Promises
async/await est du sucre syntaxique sur les Promises.
Si tu n'as jamais ecrit une Promise a la main, tu ne sais pas
ce qui se passe quand ton await echoue, quand tu oublies
le try/catch, ou pourquoi ton code "asynchrone" bloque parfois.
// Ce que l'IA ecrit :
const data = await fetch('/api/users').then(r => r.json());
// Ce que tu devrais comprendre d'abord :
const promise = fetch('/api/users'); // retourne une Promise, pas les donnees
promise.then(response => { // .then() est appele quand la reponse arrive
return response.json(); // .json() retourne AUSSI une Promise
}).then(data => {
console.log(data); // les donnees reelles
}).catch(error => {
console.error('Erreur reseau:', error);
});
// async/await est plus lisible, mais c'est la meme mecanique en dessous.
// Si tu ne comprends pas les Promises, tu ne peux pas debugger async/await.
Piege 4 : Sauter le JS vanilla pour aller direct aux frameworks
React, Vue, Angular, tout le monde veut commencer par la. C'est la pire
decision d'apprentissage possible. Les frameworks cachent JavaScript.
useState cache le state management. JSX cache la manipulation du DOM.
Le bundler cache les modules. Tu apprends le framework, pas le langage.
Et quand le framework change (ce qui arrive tous les 2 ans), tu repars de zero.
Piege 5 : Ignorer l'event loop
JavaScript est single-threaded avec un event loop. Si tu ne comprends pas ca,
tu ne comprends pas pourquoi setTimeout(fn, 0) n'execute pas
fn immediatement, pourquoi une boucle for lourde
bloque l'interface, ou comment Node.js gere des milliers de requetes simultanees
avec un seul thread.
console.log('1');
setTimeout(() => {
console.log('2');
}, 0);
Promise.resolve().then(() => {
console.log('3');
});
console.log('4');
// Sortie : 1, 4, 3, 2
// Pas 1, 2, 3, 4. Pas 1, 4, 2, 3.
// Pourquoi ? Microtasks (Promises) passent AVANT macrotasks (setTimeout).
// Si tu ne sais pas ca, tu ne peux pas raisonner sur du code asynchrone.
Le workflow qui marche : ecrire d'abord, demander ensuite
Meme discipline que pour n'importe quel langage (j'en parle aussi dans le guide Python) : ecrire d'abord, demander la review ensuite, reecrire soi-meme. Mais adapte aux specificites JS.
Etape 1 : Ecrire ta version, meme moche
Probleme : filtrer un tableau d'objets et transformer le resultat.
Ecris ta solution, meme en 20 lignes avec des boucles for.
// Ma version, trouver les utilisateurs actifs et extraire leurs noms
function getActiveUserNames(users) {
const result = [];
for (let i = 0; i < users.length; i++) {
if (users[i].active === true) {
result.push(users[i].name.toUpperCase());
}
}
return result;
}
Etape 2 : Demander la review, pas la solution
Voici mon code JavaScript pour filtrer des utilisateurs actifs et extraire leurs noms. Ne me donne pas une version corrigee. Dis-moi ce qui pourrait etre ameliore et pourquoi, et laisse-moi reecrire moi-meme.
Claude va pointer : la comparaison === true est redondante si
active est deja un booleen. La boucle for classique
peut etre remplacee par filter + map pour exprimer
l'intention. Mais il te laisse reecrire.
Etape 3 : Reecrire toi-meme
// Ma version amelioree apres review
function getActiveUserNames(users) {
return users
.filter(user => user.active)
.map(user => user.name.toUpperCase());
}
Tu as ecrit les deux versions. Tu comprends la difference entre une boucle
imperative et une chaine fonctionnelle. Tu sais que filter
retourne un nouveau tableau (pas de mutation), que map transforme
chaque element. C'est dans ta tete.
Etape 4 : Demander "qu'est-ce que je ne vois pas ?"
Voici ma version amelioree. Qu'est-ce que je ne vois pas ? Y a-t-il un cas ou cette approche pose probleme ?
Claude va mentionner : filter + map parcourt
le tableau deux fois. Pour des milliers d'elements, reduce
fait les deux en un seul passage. Et si user.name peut etre
null, ca explose sans optional chaining.
// Version defensive avec reduce
function getActiveUserNames(users) {
return users.reduce((names, user) => {
if (user.active) {
names.push(user.name?.toUpperCase() ?? 'UNKNOWN');
}
return names;
}, []);
}
Trois approches, trois niveaux de comprehension. Tu as ecrit les deux premieres.
La troisieme, tu la comprends parce que tu as fait le chemin : reduce
n'est plus magique, c'est un for deguise avec un accumulateur.
Les prompts qui forment (vs ceux qui assistent)
La difference entre apprendre et deleguer tient a la formulation du prompt. Voici les patterns adaptes a JavaScript.
| ❌ Prompt passif | ✅ Prompt pedagogique |
|---|---|
| "Ecris une fonction qui debounce un input" | "J'ai essaye d'ecrire un debounce avec setTimeout. Mon timer ne se reset pas quand je retape. Qu'est-ce que je rate ?" |
| "Corrige ce code async" | "Ce fetch retourne undefined au lieu des donnees. J'ai mis await mais ca ne change rien. Explique-moi ce qui se passe sans me donner le fix." |
| "Ecris un event listener pour un formulaire" | "J'ai fait form.addEventListener('submit', handleSubmit) mais la page se recharge. Pourquoi et comment l'empecher ?" |
| "Fais-moi un appel API avec fetch" | "J'ai ecrit ce fetch POST. Pourquoi je dois appeler .json() separement ? Et que se passe-t-il si le serveur renvoie un 404, est-ce que le catch se declenche ?" |
| "C'est quoi les closures ?" | "J'ai compris qu'une closure capture les variables du scope parent. Mais dans cette boucle for avec var, chaque callback affiche le meme nombre. Pourquoi ?" |
Le pattern commun : montrer ce que tu as fait ou compris, puis poser une question
precise. Pas "explique-moi les Promises" mais "j'ai compris .then()
mais je ne vois pas pourquoi mon .catch() n'attrape pas l'erreur du deuxieme
.then()". Claude adapte sa reponse a ton niveau reel.
Le parcours : de zero a autonome en 8 semaines
Un chemin qui a marche pour des gens que j'ai accompagnes. La regle d'or : pas de framework avant la semaine 7. Oui, ca demange. Non, ce n'est pas negociable.
Semaines 1-2 : Les bases pures (pas de framework, pas de React)
Variables (const par defaut, let quand tu dois reassigner,
jamais var), types primitifs, conditions, boucles,
fonctions, arrow functions. Sans Claude.
Utilise MDN Web Docs
, c'est la meilleure reference JS qui existe, et elle est gratuite.
Exercice : ecrire un script Node.js (pas de navigateur) qui lit un fichier JSON,
filtre les donnees selon un critere, et ecrit le resultat dans un nouveau fichier.
Juste fs.readFileSync, JSON.parse, filter,
JSON.stringify, fs.writeFileSync.
Quand c'est fait, demande a Claude de review.
Semaines 3-4 : DOM, evenements, fetch
document.querySelector, addEventListener,
createElement, classList, fetch.
Tu construis des pages interactives sans framework.
Ici tu commences a utiliser Claude en mode review.
Exercice : une todo-list en vanilla JS. Un input, un bouton, une liste.
Ajout, suppression, toggle complete. Persistence dans localStorage.
Zero dependance. Si tu as besoin de jQuery pour ca, c'est que tu ne connais pas
encore le DOM, et c'est exactement le but de l'exercice.
Semaines 5-6 : Node.js, npm, modules
import/export (ES modules), package.json,
npm, node:fs/promises, node:path, serveur HTTP basique.
Claude devient un professeur de patterns : "pourquoi ES modules
plutot que CommonJS ?", "quand utiliser require vs import ?",
"pourquoi node:fs/promises et pas fs avec des callbacks ?".
Exercice : une petite API REST avec le module http natif de Node.
Pas Express, pas Fastify, juste http.createServer. Routes manuelles,
parsing du body, reponse JSON. Tu vas comprendre exactement ce qu'Express
fait pour toi (et ca rendra Express 10x plus clair quand tu l'utiliseras).
Semaines 7-8 : Un vrai projet complet
Maintenant tu peux toucher a un framework, mais tu sais ce qui se passe en dessous. Quelques idees calibrees :
- Un SPA vanilla avec routing cote client (
popstate), templates HTML, fetch vers une API publique - Une API Express avec validation, middleware d'authentification, persistance fichier JSON
- Un outil CLI Node.js publiable sur npm :
process.argv, couleurs terminal, gestion d'erreurs - Un dashboard temps reel avec WebSocket, serveur Node + page vanilla qui affiche les updates
Claude passe en mode pair programming : tu ecris une fonctionnalite, tu discutes l'architecture avec lui, il challenge tes choix. "Pourquoi tu stockes l'etat dans une variable globale plutot que dans un objet ?" , si tu ne peux pas repondre, c'est que tu n'as pas encore decide consciemment.
Claude Pro vs Claude Code : quel outil pour apprendre JS
Deux outils, deux contextes d'execution tres differents pour JavaScript.
Claude Pro (claude.ai), le professeur
Interface web, conversation. Le bon outil pour :
- Comprendre un concept : "explique-moi l'event loop avec un exemple concret"
- Review de code : coller ton code et demander un feedback structure
- Experimenter dans la console navigateur : tu copies un snippet, tu le colles dans DevTools, tu vois le resultat en direct. Claude Pro est ideal pour ces allers-retours rapides.
- Preparer un entretien : "pose-moi 5 questions JavaScript de niveau intermediaire sur les closures et le prototypage"
Avantage : accessible, pas besoin de terminal, ideal pour les semaines 1-4 quand tu travailles dans la console du navigateur. Limite : il ne voit pas ton projet, tu copies-colles.
Claude Code, le pair programmer
Dans le terminal, directement dans ton projet. Le bon outil pour :
- Travailler dans le contexte reel : Claude voit tes fichiers, ton
package.json, tes tests - Configurer l'outillage : ESLint, Prettier, Vitest, TypeScript : Claude les installe, les configure, et t'explique chaque regle
- Refactorer progressivement : "ce fichier fait 300 lignes avec des callbacks imbriques, aide-moi a le decouper en modules ES"
- Debugger Node.js en live : il lance le script, voit l'erreur, t'explique la cause
Avantage : contexte complet du projet, execution reelle, gestion des fichiers. Limite : plus technique a installer, necessite un terminal.
La combinaison ideale
Semaines 1-4 : Claude Pro + la console du navigateur. Tu ouvres DevTools (F12), tu testes des snippets, tu poses des questions a Claude sur ce que tu observes. Pas besoin de Node ni de terminal a ce stade. Semaines 5-8 : Claude Code dans ton projet Node.js. Tu as besoin du contexte fichier, des modules, des tests, du debug en live. Claude Pro reste utile pour les questions conceptuelles en parallele.
Les conventions que l'IA ne t'apprendra pas
Claude ecrit du JavaScript correct. Mais du code correct et du code professionnel sont deux choses differentes. Ces conventions s'apprennent en lisant du bon code et en se faisant corriger, pas en demandant "ecris-moi un script".
- ESLint + Prettier des le premier jour : pas "quand le projet sera plus gros". Des le premier fichier. ESLint attrape les bugs, Prettier formate. Les deux sont non-negociables. L'IA ne te dira jamais "configure ton linter" spontanement.
constpar defaut :letuniquement quand tu dois reassigner. Jamaisvar. Claude respecte ca, mais il ne t'expliquera pas pourquoivarest problematique (hoisting, scope de fonction au lieu de scope de bloc) sauf si tu demandes.- ES modules, pas CommonJS :
import/exportest le standard.require()est legacy. L'IA melange souvent les deux dans un meme projet. - Nommage :
camelCasepour les variables et fonctions,PascalCasepour les classes et composants : ca a l'air basique, mais l'IA ne corrigera pas unget_user_nameengetUserNamesi tu ne le signales pas. - Les callbacks nommes > les callbacks anonymes :
button.addEventListener('click', handleClick)est plus lisible et debuggable quebutton.addEventListener('click', () => { ... }). Les stack traces te remercieront. - Gerer les erreurs async explicitement : chaque
fetcha sontry/catch, chaque Promise a son.catch(). L'IA oublie regulierement lecatchsur les Promises non-awaited, et c'est toi qui auras lesUnhandledPromiseRejectionen prod.
Mesurer ta progression
Comment savoir si tu apprends vraiment le JavaScript ou si tu deviens un operateur de prompt avec une console ouverte ? Trois tests concrets.
Test 1 : Le tableau blanc. Prends un probleme que tu as resolu avec
Claude la semaine derniere. Reecris-le de memoire dans un fichier vide,
sans IA, sans MDN. Si tu bloques sur la syntaxe de reduce
ou sur comment attacher un event listener, tu n'as pas appris, tu as delegue.
Test 2 : L'explication. Ouvre la console DevTools. Ecris un bout
de code que tu as utilise cette semaine. Explique chaque ligne a voix haute.
Si tu dis "cette partie je sais pas trop ce que ca fait" devant un
.bind(this) ou un ?., c'est un trou dans ta comprehension.
Test 3 : Le debug sans filet. Ouvre un projet que tu as fait
avec Claude. Introduis un bug : change un === en ==,
oublie un await, mets un var a la place d'un let
dans une boucle. Ferme Claude. Trouve le bug avec les DevTools, console.log,
et le debugger. Le temps que tu mets mesure ton autonomie reelle.
Envie de pratiquer ce parcours pour de vrai ? Le cours JavaScript de ce site reprend ces bases leçon par leçon : du code que tu exécutes directement dans la page, des quiz, et des projets corrigés construits avec l'IA. On apprend en faisant, pas en lisant.
Conclusion
JavaScript est le langage ou le copier-coller fait le plus de degats. Parce qu'il est partout, parce qu'il a plus de pieges implicites que n'importe quel autre langage mainstream, et parce que l'ecosysteme de frameworks encourage a construire sans comprendre les fondations. L'IA amplifie ce probleme, ou le resout, selon comment tu l'utilises.
La discipline est la meme : ecrire d'abord, demander ensuite, reecrire soi-meme. Mais en JavaScript, il y a une regle supplementaire : apprendre le langage avant le framework. Deux mois de vanilla JS rendent React, Vue ou Angular transparents. Deux mois de React sans vanilla JS rendent tout opaque.
Le meme workflow s'applique a n'importe quel langage. J'ai ecrit des guides equivalents pour Go et Python. Le guide PHP arrive bientot.