JS
Cours Complet de Programmation
Du débutant au niveau avancé — ES6+ inclus
Dynamique Interprété Multi-paradigme Universel
15 chapitres · Exemples pratiques · Exercices commentés · ES6+ & APIs modernes
Table des Matières
Chapitre 1 — Introduction à JavaScript — Histoire & Environnement
Chapitre 2 — Variables, Types de Données & Portée
Chapitre 3 — Opérateurs & Expressions
Chapitre 4 — Structures de Contrôle — Conditions & Boucles
Chapitre 5 — Fonctions — Déclaration, Expression & Closures
Chapitre 6 — Tableaux (Arrays) & Méthodes Fonctionnelles
Chapitre 7 — Objets & Prototypes
Chapitre 8 — Classes & Programmation Orientée Objet (ES6+)
Chapitre 9 — Déstructuration, Spread & Rest
Chapitre 10 — Modules ES6 — import / export
Chapitre 11 — Gestion des Erreurs & Exceptions
Chapitre 12 — JavaScript Asynchrone — Callbacks, Promises & async/await
Chapitre 13 — Le DOM & Événements
Chapitre 14 — APIs Web Modernes — Fetch, LocalStorage, Web APIs
Chapitre 15 — Bonnes Pratiques, Outils & Écosystème
Chapitre 1 — Introduction à JavaScript
Qu'est-ce que JavaScript ?
JavaScript (JS) est le seul langage de programmation natif des navigateurs web. Créé en 10 jours en 1995 par
Brendan Eich chez Netscape, il est aujourd'hui l'un des langages les plus utilisés au monde. Standardisé sous
le nom ECMAScript (ES), il évolue chaque année depuis ES2015 (ES6).
Caractéristique Description
Interprété / JIT Exécuté directement par le moteur JS (V8, SpiderMonkey…)
Dynamiquement typé Les types sont déterminés à l'exécution, pas à la compilation
Multi-paradigme Impératif, orienté objet ET fonctionnel
Single-threaded Un seul fil d'exécution, mais modèle asynchrone puissant
Universel Front-end (navigateur), Back-end ([Link]), Mobile, Desktop
Prototype-based L'héritage se fait via des prototypes (pas de classes au sens strict)
Versions clés d'ECMAScript
• ES5 (2009) — 'use strict', JSON, [Link]/map/filter
• ES6 / ES2015 — let/const, classes, arrow functions, Promises, modules, destructuration
• ES2017 — async/await, [Link]/values
• ES2020 — Optional chaining (?.), Nullish coalescing (??), BigInt
• ES2022 — Top-level await, [Link](), [Link]()
• ES2024 — [Link](), groupBy, [Link]()
Environnements d'exécution
// Dans le navigateur — accès au DOM, fetch, localStorage…
[Link]("Hello depuis le navigateur !");
// Dans [Link] — accès au système de fichiers, réseau…
// node [Link]
const fs = require('fs');
// Vérifier l'environnement
const estNavigateur = typeof window !== 'undefined';
const estNode = typeof process !== 'undefined';
■ Conseil : Utilisez les DevTools du navigateur (F12 → Console) pour tester rapidement du code JavaScript.
Chapitre 2 — Variables, Types de Données & Portée
Déclaration de variables
Mot-clé Portée Réassignable Hoisting Usage
var Fonction Oui Oui (undefined) Éviter — héritage ES5
let Bloc {} Oui Non (TDZ) Variables mutables
const Bloc {} Non Non (TDZ) Valeurs constantes
const nom = "Alice"; // string — ne peut pas être réassigné
let age = 30; // number — peut changer
var ancien = "déprécié"; // var — éviter
// TDZ (Temporal Dead Zone) avec let/const
// [Link](x); // ReferenceError !
let x = 5;
// const sur un objet : la référence est constante, pas le contenu
const personne = { nom: "Bob" };
[Link] = "Charlie"; // OK — on modifie l'objet
// personne = {}; // TypeError — réassignation interdite
Les 7 types primitifs
Type Description Exemples
string Texte, immuable 'bonjour', "monde", `${expr}`
number Entier ET décimal (64 bits) 42, 3.14, NaN, Infinity, -0
bigint Entiers arbitrairement grands 9007199254740993n, BigInt(42)
boolean Vrai ou faux true, false
undefined Variable non initialisée let x; // x est undefined
Absence intentionnelle de
null const val = null;
valeur
symbol Identifiant unique et immutable Symbol('description')
Types reference (objets)
// Tout ce qui n'est pas primitif est un objet
typeof {} // "object"
typeof [] // "object" (tableau = objet spécial)
typeof function(){} // "function"
typeof null // "object" ← bug historique de JS !
// Vérifier correctement
[Link]([]) // true
null === null // true
typeof x === 'undefined' // true
Conversions de types
// Conversion implicite (coercition) — source de bugs !
"5" + 3 // "53" — number converti en string
"5" - 3 // 2 — string converti en number
true + 1 // 2
false + 1 // 1
null + 1 // 1
undefined + 1 // NaN
// Conversion explicite — recommandée
Number("42") // 42
Number("abc") // NaN
parseInt("42px") // 42
parseFloat("3.14") // 3.14
String(42) // "42"
Boolean(0) // false
Boolean("") // false ← valeurs "falsy"
Boolean([]) // true ← objet vide = truthy !
// Valeurs falsy : false, 0, -0, 0n, "", null, undefined, NaN
Chapitre 3 — Opérateurs & Expressions
Opérateurs arithmétiques
let a = 10, b = 3;
a + b // 13 — addition
a - b // 7 — soustraction
a * b // 30 — multiplication
a / b // 3.333... — division (toujours décimale en JS !)
a % b // 1 — modulo
a ** b // 1000 — puissance (ES2016)
a++ // incrémentation (post)
++a // incrémentation (pré)
a-- // décrémentation
Opérateurs de comparaison
// == avec coercition (éviter)
"5" == 5 // true ← coercition de type
null == undefined // true
// === sans coercition (toujours utiliser ça)
"5" === 5 // false ← types différents
5 === 5 // true
// Autres comparaisons
5 != "5" // false (avec coercition)
5 !== "5" // true (sans coercition — préférer)
10 > 5 // true
10 >= 10 // true
■ Attention : Toujours utiliser === et !== pour éviter les surprises liées à la coercition de type.
Opérateurs logiques & modernes
// Logique classique
true && false // false — ET
true || false // true — OU
!true // false — NON
// Court-circuit (short-circuit)
const val = null || "défaut"; // "défaut"
const nom = user && [Link]; // undefined si user est falsy
// Nullish Coalescing ?? (ES2020) — seulement null/undefined
const score = null ?? 0; // 0
const pts = 0 ?? 100; // 0 ← 0 n'est pas null !
const pts2 = 0 || 100; // 100 ← 0 est falsy avec ||
// Optional Chaining ?. (ES2020)
const ville = user?.adresse?.ville; // undefined si user ou adresse est null/undefined
const lg = arr?.[0]; // accès tableau sécurisé
const res = obj?.methode?.(); // appel de méthode sécurisé
// Affectation logique (ES2021)
x ||= "défaut"; // x = x || "défaut"
x &&= x * 2; // x = x && x * 2
x ??= 0; // x = x ?? 0
// Ternaire
const msg = age >= 18 ? "Majeur" : "Mineur";
Opérateur typeof & instanceof
typeof 42 // "number"
typeof "bonjour" // "string"
typeof true // "boolean"
typeof undefined // "undefined"
typeof {} // "object"
typeof [] // "object"
typeof null // "object" ← piège !
typeof function(){} // "function"
typeof Symbol() // "symbol"
typeof 42n // "bigint"
// instanceof — teste la chaîne de prototype
[] instanceof Array // true
{} instanceof Object // true
new Date() instanceof Date // true
Chapitre 4 — Structures de Contrôle
Conditions
// if / else if / else
const note = 14;
if (note >= 16) {
[Link]("Très bien");
} else if (note >= 12) {
[Link]("Bien");
} else if (note >= 10) {
[Link]("Passable");
} else {
[Link]("Insuffisant");
}
// switch — comparaison stricte (===)
const jour = "lundi";
switch (jour) {
case "lundi":
case "mardi":
[Link]("Début de semaine"); break;
case "vendredi":
[Link]("TGIF !"); break;
default:
[Link]("Milieu de semaine");
}
// Ternaire — pour des expressions simples
const acces = age >= 18 ? "autorisé" : "refusé";
// if one-liner (sans accolades — déconseillé sauf trivial)
if (debug) [Link]("Mode débogage");
Boucles
// for classique
for (let i = 0; i < 5; i++) {
[Link](i); // 0 1 2 3 4
}
// while
let n = 10;
while (n > 0) {
[Link](n);
n -= 3;
}
// do...while (exécuté au moins une fois)
let saisie;
do {
saisie = prompt("Entrez un nombre positif :");
} while (saisie <= 0);
// for...of — itère sur les VALEURS (Array, String, Map, Set…)
const fruits = ["pomme", "poire", "cerise"];
for (const fruit of fruits) {
[Link](fruit);
}
// for...in — itère sur les CLÉS d'un objet
const personne = { nom: "Alice", age: 30 };
for (const cle in personne) {
[Link](cle, ":", personne[cle]);
}
// break & continue
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) continue; // saute les pairs
if (i > 7) break; // sort à 7
[Link](i); // 1, 3, 5, 7
}
■ Conseil : Préférez for...of aux boucles for classiques pour itérer sur des tableaux — c'est plus lisible et moins
sujet aux erreurs d'index.
Chapitre 5 — Fonctions — Déclaration, Expression &
Closures
Les différentes formes de fonctions
// 1. Déclaration de fonction (hoistée — utilisable avant sa définition)
function addition(a, b) {
return a + b;
}
// 2. Expression de fonction (non hoistée)
const soustraction = function(a, b) {
return a - b;
};
// 3. Fonction fléchée / Arrow function (ES6) — syntaxe concise
const multiplication = (a, b) => a * b;
const carre = n => n * n; // un seul paramètre : pas de ()
const direBonjour = () => "Bonjour !"; // pas de paramètre
// Corps avec accolades → return obligatoire
const division = (a, b) => {
if (b === 0) throw new Error("Division par zéro");
return a / b;
};
// 4. Méthode dans un objet
const calc = {
pi: 3.14159,
cercle(r) { return [Link] * r * r; }, // méthode courte (ES6)
carre: function(c) { return c * c; }
};
Paramètres avancés
// Valeurs par défaut (ES6)
function saluer(nom = "inconnu", ponctuation = "!") {
return `Bonjour, ${nom}${ponctuation}`;
}
saluer(); // "Bonjour, inconnu!"
saluer("Alice", "."); // "Bonjour, Alice."
// Rest parameters — capture les arguments restants
function somme(premier, ...autres) {
return [Link]((acc, n) => acc + n, premier);
}
somme(1, 2, 3, 4); // 10
// Arguments object (ancien, ES5)
function ancien() {
[Link](arguments); // objet array-like, pas un vrai tableau
}
Closures & Portée
// Une closure capture les variables de son environnement lexical
function compteur(debut = 0) {
let valeur = debut; // variable capturée
return {
incrementer() { valeur++; },
decrementer() { valeur--; },
lire() { return valeur; }
};
}
const c1 = compteur(10);
const c2 = compteur(0);
[Link]();
[Link]();
[Link]([Link]()); // 12
[Link]([Link]()); // 0 — c2 a sa propre variable valeur
// Cas classique avec boucle (piège !)
for (var i = 0; i < 3; i++) {
setTimeout(() => [Link](i), 100); // affiche 3, 3, 3 !
}
for (let i = 0; i < 3; i++) { // let crée une nouvelle portée
setTimeout(() => [Link](i), 100); // affiche 0, 1, 2
}
Fonctions d'ordre supérieur (Higher-Order Functions)
// Une fonction qui prend une autre fonction en paramètre
function appliquer(fn, valeur) {
return fn(valeur);
}
appliquer(x => x * 2, 5); // 10
// Une fonction qui retourne une fonction
function multiplierPar(facteur) {
return (nombre) => nombre * facteur;
}
const double = multiplierPar(2);
const triple = multiplierPar(3);
double(5); // 10
triple(5); // 15
// Composition de fonctions
const compose = (...fns) => x => [Link]((v, f) => f(v), x);
const pipe = (...fns) => x => [Link]((v, f) => f(v), x);
const traiter = pipe(
x => x * 2,
x => x + 1,
x => [Link]()
);
traiter(5); // "11"
Chapitre 6 — Tableaux (Arrays) & Méthodes
Fonctionnelles
Création & accès
const vide = [];
const notes = [18, 14, 12, 16, 10];
const mixte = [1, "deux", true, null, {a: 3}];
notes[0] // 18 — premier élément
[Link](-1) // 10 — dernier (ES2022)
[Link] // 5
// Tableaux 2D
const matrice = [[1,2,3], [4,5,6], [7,8,9]];
matrice[1][2] // 6
Méthodes de mutation (modifient le tableau)
const arr = [1, 2, 3];
[Link](4); // ajoute à la fin → [1,2,3,4]
[Link](); // retire le dernier → [1,2,3]
[Link](0); // ajoute au début → [0,1,2,3]
[Link](); // retire le premier → [1,2,3]
[Link](1, 1); // retire 1 élément à l'index 1 → [1,3]
[Link](1, 0, 2); // insère 2 à l'index 1 → [1,2,3]
[Link](); // inverse → [3,2,1]
[Link]((a,b) => a - b); // tri numérique croissant → [1,2,3]
[Link](0, 1, 3); // remplit index 1 à 3 avec 0
Méthodes fonctionnelles (retournent un nouveau tableau)
const nombres = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// map — transforme chaque élément
const doubles = [Link](n => n * 2); // [2,4,6,8,10,12,14,16,18,20]
// filter — filtre selon une condition
const pairs = [Link](n => n % 2 === 0); // [2,4,6,8,10]
// reduce — réduit en une valeur
const somme = [Link]((acc, n) => acc + n, 0); // 55
const max = [Link]((a, b) => a > b ? a : b);// 10
// find / findIndex
const premier = [Link](n => n > 5); // 6
const index = [Link](n => n > 5); // 5
// some / every
[Link](n => n > 9); // true — au moins un
[Link](n => n > 0); // true — tous
// includes / indexOf
[Link](5); // true
[Link](5); // 4
// flat / flatMap
[[1,2],[3,4]].flat(); // [1,2,3,4]
[1,2,3].flatMap(n => [n, n*2]); // [1,2,2,4,3,6]
// slice — extrait sans modifier
[Link](2, 5); // [3,4,5]
// Chaînage
const resultat = nombres
.filter(n => n % 2 === 0)
.map(n => n ** 2)
.reduce((acc, n) => acc + n, 0); // 4+16+36+64+100 = 220
Méthode Retourne Mute ? Usage
map(fn) Nouveau tableau Non Transformer chaque élément
filter(fn) Nouveau tableau Non Garder les éléments valides
reduce(fn,v) Une valeur Non Agréger en une seule valeur
forEach(fn) undefined Non Effets de bord (logging…)
find(fn) Élément ou undef Non Premier élément correspondant
sort(fn) Même tableau Oui Trier — attention, mute !
splice() Éléments retirés Oui Insérer / supprimer en place
Chapitre 7 — Objets & Prototypes
Création et manipulation d'objets
// Littéral d'objet
const personne = {
prenom: "Alice",
nom: "Dupont",
age: 30,
// Méthode (ES6 — syntaxe courte)
sePresenter() {
return `Je m'appelle ${[Link]} ${[Link]}`;
},
// Getter / Setter
get nomComplet() { return `${[Link]} ${[Link]}`; },
set nomComplet(val) {
[[Link], [Link]] = [Link](" ");
}
};
[Link] = "Paris"; // ajout de propriété
delete [Link]; // suppression
"prenom" in personne; // true — vérifie l'existence
[Link]("ville"); // true — propriété propre (pas héritée)
// Accès dynamique
const cle = "prenom";
personne[cle]; // "Alice"
// [Link] / values / entries
[Link](personne); // ["prenom", "nom", "ville", "sePresenter", ...]
[Link](personne); // ["Alice", "Dupont", "Paris", ...]
[Link](personne); // [["prenom","Alice"], ["nom","Dupont"], ...]
// Copie & fusion
const copie = { ...personne }; // shallow copy
const fusion = { ...obj1, ...obj2 }; // merge
const profonde = [Link]([Link](personne)); // deep copy (limité)
// [Link]
[Link]({}, personne, { age: 31 }); // shallow merge
// Geler un objet (immuable)
const config = [Link]({ env: "prod", version: "1.0" });
Prototypes & Chaîne de prototypes
// Chaque objet a un prototype (__proto__)
const animal = {
respirer() { [Link](`${[Link]} respire`); }
};
const chien = [Link](animal); // chien hérite de animal
[Link] = "Rex";
[Link] = function() { [Link]("Ouaf !"); };
[Link](); // "Ouaf !" — méthode propre
[Link](); // "Rex respire" — méthode héritée via le prototype
// La chaîne : chien → animal → [Link] → null
// Vérifier
[Link](chien) === animal; // true
chien instanceof Object; // true
Chapitre 8 — Classes & Programmation Orientée
Objet (ES6+)
// Déclaration de classe
class Animal {
// Champ privé (ES2022)
#energie = 100;
constructor(nom, espece) {
[Link] = nom;
[Link] = espece;
}
// Getter
get energie() { return this.#energie; }
// Méthode d'instance
manger(quantite = 10) {
this.#energie += quantite;
[Link](`${[Link]} mange. Énergie : ${this.#energie}`);
}
// Méthode statique
static comparer(a, b) {
return [Link]([Link]);
}
toString() { return `${[Link]} nommé ${[Link]}`; }
}
// Héritage avec extends
class Chien extends Animal {
#race;
constructor(nom, race) {
super(nom, "Canidé"); // appel obligatoire avant this
this.#race = race;
}
aboyer(fois = 1) {
[Link]("Ouaf ! ".repeat(fois).trim());
}
toString() {
return `${[Link]()} (${this.#race})`;
}
}
const rex = new Chien("Rex", "Labrador");
[Link](20); // Rex mange. Énergie : 120
[Link](3); // Ouaf ! Ouaf ! Ouaf !
[Link]([Link]()); // Canidé nommé Rex (Labrador)
[Link](rex instanceof Chien); // true
[Link](rex instanceof Animal); // true
// Mixin — composition plutôt qu'héritage profond
const Nageable = (Base) => class extends Base {
nager() { [Link](`${[Link]} nage !`); }
};
class Labrador extends Nageable(Chien) {}
new Labrador("Splash", "Labrador").nager();
✔ Bonne pratique : En JavaScript, les classes sont du sucre syntaxique sur le système de prototypes. Sous le
capot, tout reste basé sur [Link]().
Chapitre 9 — Déstructuration, Spread & Rest
Déstructuration de tableaux
const [a, b, c] = [1, 2, 3];
[Link](a, b, c); // 1 2 3
// Ignorer des éléments
const [premier, , troisieme] = [10, 20, 30]; // 10, 30
// Valeur par défaut
const [x = 0, y = 0] = [5]; // x=5, y=0
// Swap élégant
let m = 1, n = 2;
[m, n] = [n, m]; // m=2, n=1
// Rest dans un tableau
const [head, ...tail] = [1, 2, 3, 4, 5];
// head = 1, tail = [2, 3, 4, 5]
Déstructuration d'objets
const personne = { prenom: "Alice", age: 30, ville: "Paris" };
// Basique
const { prenom, age } = personne;
// Renommage
const { prenom: firstName, age: annees } = personne;
// Valeur par défaut
const { pays = "France", ville } = personne;
// Imbriquée
const { adresse: { rue, cp } = {} } = user;
// Dans les paramètres de fonction
function afficher({ nom, age = 0, ville = "?" }) {
[Link](`${nom}, ${age} ans, ${ville}`);
}
afficher(personne);
Spread Operator (...)
// Copier / fusionner des tableaux
const a = [1, 2, 3];
const b = [4, 5, 6];
const fusion = [...a, ...b]; // [1,2,3,4,5,6]
const copie = [...a]; // copie superficielle
// Passer un tableau en arguments
[Link](...[3, 1, 4, 1, 5]); // 5
// Copier / fusionner des objets
const base = { a: 1, b: 2 };
const etendu = { ...base, c: 3 }; // {a:1, b:2, c:3}
const override = { ...base, b: 99 }; // {a:1, b:99} — b écrasé
// Convertir itérable en tableau
const chars = [..."hello"]; // ['h','e','l','l','o']
const unique = [...new Set(chars)]; // ['h','e','l','o']
Chapitre 10 — Modules ES6 — import / export
// ■■ [Link] ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// Export nommé
export const PI = 3.14159;
export function addition(a, b) { return a + b; }
export function soustraction(a, b) { return a - b; }
// Export par défaut (un seul par fichier)
export default class Calculatrice {
additionner(a, b) { return a + b; }
}
// ■■ [Link] ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// Import nommé
import { PI, addition } from './[Link]';
// Import avec alias
import { soustraction as sub } from './[Link]';
// Import par défaut
import Calculatrice from './[Link]';
// Import tout (namespace)
import * as math from './[Link]';
[Link](1, 2);
// Import dynamique (lazy loading)
const module = await import('./[Link]');
// Re-export
export { addition, soustraction } from './[Link]';
export { default as Calc } from './[Link]';
// Dans le HTML
//
Type d'export Syntaxe d'export Syntaxe d'import
Nommé export const x = 1 import { x } from './m'
Par défaut export default function f(){} import f from './m'
Renommé export export { x as y } import { y } from './m'
Renommé import export const x = 1 import { x as z } from './m'
Tout export { a, b, c } import * as ns from './m'
Dynamique (n'importe lequel) const m = await import('./m')
■ Conseil : Dans [Link], utilisez l'extension .mjs ou ajoutez "type": "module" dans [Link] pour utiliser les
modules ES6.
Chapitre 11 — Gestion des Erreurs & Exceptions
// try / catch / finally
try {
const data = [Link]("{ invalide }"); // SyntaxError
const res = [Link]; // TypeError
} catch (err) {
[Link]([Link]); // "SyntaxError"
[Link]([Link]); // message d'erreur
[Link]([Link]); // pile d'appels complète
} finally {
[Link]("Toujours exécuté — nettoyage ici");
}
// Types d'erreurs natifs
new Error("erreur générique")
new TypeError("mauvais type")
new RangeError("valeur hors plage")
new ReferenceError("variable inexistante")
new SyntaxError("syntaxe invalide")
new URIError("URI malformée")
// Erreurs personnalisées
class ValidationError extends Error {
constructor(message, champ) {
super(message);
[Link] = "ValidationError";
[Link] = champ;
}
}
class HttpError extends Error {
constructor(status, message) {
super(message);
[Link] = "HttpError";
[Link] = status;
}
}
// Utilisation
function validerAge(age) {
if (typeof age !== "number") throw new TypeError("L'âge doit être un nombre");
if (age < 0 || age > 150) throw new RangeError("Âge invalide : " + age);
if () throw new ValidationError("Âge entier requis", "age");
return true;
}
try {
validerAge(-5);
} catch (err) {
if (err instanceof ValidationError) {
[Link]("Champ invalide :", [Link]);
} else if (err instanceof RangeError) {
[Link]("Plage invalide :", [Link]);
} else {
throw err; // re-throw les erreurs non gérées
}
}
Chapitre 12 — JavaScript Asynchrone — Callbacks,
Promises & async/await
Le modèle événementiel & Event Loop
JavaScript est single-threaded mais non-bloquant grâce à son Event Loop. Les opérations longues (réseau,
fichiers, timers) sont déléguées aux Web APIs ou à libuv ([Link]), et leurs callbacks sont mis en queue quand
ils sont prêts.
[Link]("1 — synchrone");
setTimeout(() => [Link]("3 — macrotask"), 0);
[Link]().then(() => [Link]("2 — microtask"));
[Link]("4 — synchrone");
// Affiche : 1 → 4 → 2 → 3
Callbacks (ancienne méthode)
// Callback hell — imbrication difficile à lire
[Link]("[Link]", (err, data1) => {
if (err) return handleError(err);
[Link]("[Link]", (err, data2) => {
if (err) return handleError(err);
[Link]("[Link]", data1 + data2, (err) => {
if (err) return handleError(err);
[Link]("Terminé !");
});
});
});
Promises
// Créer une Promise
const attendre = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const fetchUser = (id) => new Promise((resolve, reject) => {
if (id <= 0) return reject(new RangeError("ID invalide"));
setTimeout(() => resolve({ id, nom: "Alice" }), 500);
});
// Chaînage .then() / .catch() / .finally()
fetchUser(1)
.then(user => { [Link](user); return [Link]; })
.then(id => fetchUser(id + 1))
.catch(err => [Link]("Erreur :", [Link]))
.finally(()=> [Link]("Terminé"));
// [Link] — en parallèle, échoue si une échoue
const [a, b, c] = await [Link]([
fetchUser(1), fetchUser(2), fetchUser(3)
]);
// [Link] — attend toutes, même en cas d'échec
const results = await [Link]([fetchUser(1), fetchUser(-1)]);
[Link](r => {
if ([Link] === "fulfilled") [Link]([Link]);
else [Link]([Link]);
});
// [Link] — retourne la plus rapide
const winner = await [Link]([fetchUser(1), attendre(200).then(() => "timeout")]);
// [Link] — première réussie
const first = await [Link]([fetchUser(-1), fetchUser(2)]);
async / await — syntaxe recommandée
// async retourne toujours une Promise
async function chargerDonnees(userId) {
try {
const user = await fetchUser(userId);
const posts = await fetchPosts([Link]); // séquentiel
return { user, posts };
} catch (err) {
[Link]("Erreur chargement :", [Link]);
throw err; // re-throw pour que l'appelant puisse gérer
}
}
// Parallèle avec async/await
async function chargerParallele(ids) {
const promises = [Link](id => fetchUser(id));
const users = await [Link](promises);
return users;
}
// Top-level await (dans un module ES2022+)
const config = await fetch("/api/config").then(r => [Link]());
// Gestion d'erreur avec helper
const [err, data] = await fetchUser(1)
.then(v => [null, v])
.catch(e => [e, null]);
if (err) { /* gérer */ }
Chapitre 13 — Le DOM & Événements
Sélection d'éléments
// Sélecteurs modernes (recommandés)
[Link]("#monId"); // 1er élément avec cet id
[Link](".ma-classe"); // 1er élément avec cette classe
[Link]("h1 > span"); // sélecteur CSS complet
[Link]("[Link]"); // NodeList de TOUS les correspondants
// Anciens sélecteurs (encore utiles)
[Link]("monId");
[Link]("classe"); // HTMLCollection
[Link]("div");
// Traversal
[Link]
[Link] // enfants directs (HTMLCollection)
[Link]
[Link]
[Link]
[Link]
[Link](".conteneur") // ancêtre le plus proche
Manipulation du DOM
const el = [Link]("h1");
// Contenu
[Link] = "Nouveau titre"; // texte brut — sécurisé
[Link] = "Gras"; // HTML — attention XSS !
// Attributs
[Link]("class");
[Link]("data-id", "42");
[Link]("disabled");
[Link]; // accès aux data-attributes
// Classes CSS
[Link]("actif");
[Link]("caché");
[Link]("visible");
[Link]("actif"); // true/false
[Link]("ancien", "nouveau");
// Styles
[Link] = "red";
[Link] = "color:red; font-size:1.2em;";
getComputedStyle(el).color; // style calculé final
// Créer et insérer des éléments
const div = [Link]("div");
[Link] = "Nouveau bloc";
[Link] = "carte";
[Link](div); // à la fin de body
[Link](div); // au début
[Link]("afterend", div); // après el
[Link]("beforeend", "OK"); // HTML brut
// Supprimer
[Link]();
[Link](enfant);
Événements
// addEventListener — méthode recommandée
const btn = [Link]("#monBouton");
function handleClick(event) {
[Link]("Cliqué !", [Link], [Link]);
[Link](); // empêche comportement par défaut (liens, forms)
[Link](); // arrête la propagation (bubbling)
}
[Link]("click", handleClick);
[Link]("mouseenter", () => [Link] = "0.8");
[Link]("click", handleClick); // suppression
// Délégation d'événements — un seul listener pour plusieurs enfants
[Link]("ul").addEventListener("click", (e) => {
if ([Link]("li")) {
[Link]("Item cliqué :", [Link]);
}
});
// Événements courants
// click, dblclick, contextmenu
// mouseenter, mouseleave, mouseover, mouseout, mousemove
// keydown, keyup, keypress (déprécié)
// input, change, submit, focus, blur
// scroll, resize (utiliser avec throttle/debounce !)
// DOMContentLoaded, load, unload
// touchstart, touchend, touchmove (mobile)
// Écouter une seule fois
[Link]("click", handler, { once: true });
// Event personnalisé
const evt = new CustomEvent("monEvent", { detail: { data: 42 } });
[Link](evt);
[Link]("monEvent", e => [Link]([Link]));
Chapitre 14 — APIs Web Modernes — Fetch, Storage
& Web APIs
Fetch API — Requêtes HTTP
// GET basique
const response = await fetch("[Link]
if (![Link]) throw new Error(`HTTP ${[Link]}`);
const users = await [Link]();
// POST avec corps JSON
const newUser = await fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: [Link]({ nom: "Alice", age: 30 })
}).then(r => [Link]());
// Wrapper réutilisable
async function api(url, options = {}) {
const res = await fetch(url, {
headers: { "Content-Type": "application/json", ...[Link] },
...options,
body: [Link] ? [Link]([Link]) : undefined
});
if (![Link]) {
const error = await [Link]().catch(() => ({}));
throw new Error([Link] || `Erreur ${[Link]}`);
}
return [Link] !== 204 ? [Link]() : null;
}
// Avec timeout via AbortController
const controller = new AbortController();
const timeout = setTimeout(() => [Link](), 5000);
try {
const data = await fetch("/api/data", { signal: [Link] });
} catch (e) {
if ([Link] === "AbortError") [Link]("Requête annulée (timeout)");
} finally {
clearTimeout(timeout);
}
Web Storage — Persistance côté client
// localStorage — persiste après fermeture du navigateur
[Link]("token", "abc123");
const token = [Link]("token");
[Link]("token");
[Link]();
// Stocker des objets (JSON obligatoire)
[Link]("user", [Link]({ nom: "Alice" }));
const user = [Link]([Link]("user") || "null");
// sessionStorage — effacé à la fermeture de l'onglet
[Link]("draft", "texte temporaire");
// Cookies (plus complexes)
[Link] = "nom=Alice; max-age=86400; path=/; SameSite=Strict";
Autres APIs Web essentielles
// Geolocation
[Link](
pos => [Link]([Link], [Link]),
err => [Link]([Link])
);
// Web Notifications
if ([Link] === "granted") {
new Notification("Nouveau message !", { body: "Vous avez 3 messages" });
} else {
[Link]();
}
// Clipboard API
await [Link]("texte copié");
const texte = await [Link]();
// IntersectionObserver — lazy loading
const observer = new IntersectionObserver((entries) => {
[Link](entry => {
if ([Link]) {
[Link] = [Link];
[Link]([Link]);
}
});
}, { threshold: 0.1 });
[Link]("img[data-src]").forEach(img => [Link](img));
// MutationObserver — surveiller les changements DOM
const mutObserver = new MutationObserver(mutations => {
[Link](m => [Link]("DOM modifié :", [Link]));
});
[Link]([Link], { childList: true, subtree: true });
Chapitre 15 — Bonnes Pratiques, Outils &
Écosystème
Conventions de code
Élément Convention Exemple
Variables / fonctions camelCase userName, fetchData()
Classes PascalCase UserService, EventBus
Constantes globales UPPER_SNAKE MAX_RETRIES, API_URL
Fichiers kebab-case [Link], [Link]
Composants (React…) PascalCase [Link]
Booléens Préfixe is/has/can isLoading, hasError
Patterns essentiels
// 1. Module Pattern (IIFE)
const monModule = (() => {
let privé = 0;
return { lire: () => privé, incrementer: () => privé++ };
})();
// 2. Observer / EventEmitter
class EventEmitter {
#listeners = new Map();
on(event, fn) { (this.#[Link](event) ??
this.#[Link](event,[]).get(event)).push(fn); }
off(event, fn) { this.#[Link](event,
(this.#[Link](event)??[]).filter(f=>f!==fn)); }
emit(event,...args) { (this.#[Link](event)??[]).forEach(fn=>fn(...args)); }
}
// 3. Throttle & Debounce — performance
function debounce(fn, ms) {
let timer;
return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), ms); };
}
function throttle(fn, ms) {
let last = 0;
return (...args) => { const now=[Link](); if(now-last>=ms){last=now; fn(...args);} };
}
[Link]("resize", debounce(handleResize, 200));
[Link]("scroll", throttle(handleScroll, 100));
// 4. Mémoïsation — cache des résultats
function memoize(fn) {
const cache = new Map();
return (...args) => {
const key = [Link](args);
if ([Link](key)) return [Link](key);
const result = fn(...args);
[Link](key, result);
return result;
};
}
const fib = memoize(n => n <= 1 ? n : fib(n-1) + fib(n-2));
Outils indispensables
Catégorie Outils Usage
Gestionnaire de paquets npm, pnpm, yarn Installer et gérer les dépendances
Bundler Vite, Webpack, Rollup Grouper et optimiser les modules
Transpiler Babel, SWC, esbuild ES6+ → ES5, TypeScript → JS
Linter ESLint Détecter erreurs et mauvaises pratiques
Formateur Prettier Formater automatiquement le code
Tests Vitest, Jest, Cypress Tests unitaires, intégration, E2E
TypeScript tsc Typage statique au-dessus de JS
Frameworks Front React, Vue, Svelte, Solid Construire des interfaces réactives
Frameworks Back Express, Fastify, Hono Serveurs HTTP avec [Link]
Runtime alternatifs Deno, Bun Alternatives modernes à [Link]
Règles d'or
• Toujours utiliser const par défaut, let si réassignation nécessaire, jamais var.
• Préférer === à == pour toutes les comparaisons.
• Écrire des fonctions pures quand c'est possible — pas d'effets de bord cachés.
• Utiliser async/await plutôt que les chaînes de .then() imbriquées.
• Toujours gérer les erreurs dans les blocs asynchrones (try/catch).
• Ne jamais utiliser innerHTML avec des données non validées — risque de XSS.
• Éviter les mutations directes des tableaux/objets — préférer des copies immutables.
• Déstructurer les paramètres des fonctions pour plus de lisibilité.
• Utiliser ESLint + Prettier configurés dans le projet pour uniformiser le style.
• Écrire des tests ! Même basiques — ils évitent des régressions coûteuses.
Ressources recommandées : MDN Web Docs ([Link]) · [Link] · [Link] · [Link]
(propositions ECMAScript)