Cours JavaScript Complet ⚡
Les 12 chapitres essentiels — des bases au JavaScript moderne (ES6+), avec exemples et quiz
7. Les objets
2. Opérateurs et expressions
8. Les classes (POO)
3. Structures conditionnelles
9. Asynchrone : Promises & async/await
4. Les boucles
10. Manipulation du DOM
5. Les fonctions
11. Gestion des erreurs
6. Les tableaux (Arrays)
12. ES6+ et fonctionnalités modernes
Variables et types de données
const PI = 3.14159;
const nom = « Alice »;
// let — valeur qui peut être réassignée
let age = 25;
age = 26; // ✅ OK
// var — ancienne syntaxe, à ÉVITER
var ancien = « ne plus utiliser »; // ❌
Règle d'or : Utilisez const par défaut. Passez à let uniquement si la valeur doit changer. N'utilisez jamais var — il a des comportements imprévisibles (hoisting, pas de block scope).
| Type | Description | Exemple | typeof |
|---|---|---|---|
| string | Chaîne de caractères | « hello », 'world', `template` | « string » |
| number | Entier ou décimal | 42, 3.14, NaN, Infinity | « number » |
| bigint | Très grands entiers | 9007199254740991n | « bigint » |
| boolean | Vrai / Faux | true, false | « boolean » |
| undefined | Variable déclarée sans valeur | let x; | « undefined » |
| null | Absence intentionnelle de valeur | null | « object » ⚠️ |
| symbol | Identifiant unique | Symbol(« id ») | « symbol » |
Piège historique : typeof null retourne « object » — c'est un bug connu depuis 1995 qui n'a jamais été corrigé. Pour tester null, utilisez x === null.
const age = 25;
// Template literal avec backticks ` `
console.log(`Je m'appelle $ et j'ai $ ans.`);
console.log(`Dans 5 ans : $ ans.`);
// Multi-lignes
const html = `
$
Âge : $
`;
Number(« 42 ») // 42
Number(« hello ») // NaN
String(42) // « 42 »
Boolean(0) // false
Boolean(« ») // false
Boolean(« hello ») // true
parseInt(« 42px ») // 42 (ignore le reste)
parseFloat(« 3.14 ») // 3.14
// Coercion implicite (piège JS !)
« 5 » + 3 // « 53 » (string concat !)
« 5 » – 3 // 2 (conversion auto en number)
« 5 » * 3 // 15
true + 1 // 2
Le piège le plus courant en JS : « 5 » + 3 = « 53 » (concaténation) mais « 5 » – 3 = 2 (soustraction). L'opérateur + privilégie la concaténation si un opérande est un string.
x === null.Number("10") + 5 → 15.Opérateurs et expressions
5 == « 5 » // true ⚠️ (conversion implicite)
0 == false // true ⚠️
« » == false // true ⚠️
null == undefined // true ⚠️
// === (égalité stricte) — compare type ET valeur
5 === « 5 » // false ✅
0 === false // false ✅
null === undefined // false ✅
Règle absolue : Utilisez TOUJOURS === et !==. N'utilisez JAMAIS == et !=. Les conversions implicites de == causent des bugs subtils et imprévisibles.
true && false // false (ET)
true || false // true (OU)
!true // false (NON)
// Short-circuit — retourne la valeur, pas un booléen
« Alice » || « Bob » // « Alice » (premier truthy)
« » || « Bob » // « Bob » (premier truthy)
« Alice » && « Bob » // « Bob » (dernier truthy)
« » && « Bob » // « » (premier falsy)
// ?? (nullish coalescing) — seulement null/undefined
null ?? « défaut » // « défaut »
undefined ?? « défaut » // « défaut »
0 ?? « défaut » // 0 (0 n'est PAS null)
« » ?? « défaut » // « » (vide n'est PAS null)
// ?. (optional chaining)
const user = ;
user?.address?.city // « Paris »
user?.phone?.number // undefined (pas d'erreur !)
|| vs ?? : || traite toutes les valeurs falsy (0, « », false, null, undefined). ?? ne traite QUE null et undefined. Utilisez ?? quand 0 ou « » sont des valeurs valides.
s.length // 13 (propriété, pas méthode)
s.toUpperCase() // « HELLO, WORLD! »
s.toLowerCase() // « hello, world! »
s.trim() // Supprime espaces début/fin
s.includes(« World ») // true
s.startsWith(« He ») // true
s.indexOf(« World ») // 7 (-1 si absent)
s.replace(« World », « JS ») // « Hello, JS! »
s.split(« , « ) // [« Hello », « World! »]
s.slice(0, 5) // « Hello »
s.repeat(3) // « Hello, World!Hello, World!Hello, World! »
s.padStart(20, « * ») // « *******Hello, World! »
|| traite 0 comme falsy → retourne « default ». ?? ne réagit qu'à null/undefined → retourne 0.Structures conditionnelles
if (age < 13) else if (age < 18) else if (age < 65) else
const statut = age >= 18 ? « majeur » : « mineur »;
// Switch
switch (jour)
N'oubliez pas le break ! Sans break, le switch continue d'exécuter les cases suivants (fall-through). C'est le piège n°1 du switch en JS.
Il y a exactement 7 valeurs falsy en JS — tout le reste est truthy :
0 // le nombre zéro (et -0)
« » // string vide
null // absence de valeur
undefined // variable non assignée
NaN // Not a Number
0n // BigInt zéro
// ⚠️ Truthy surprenants :
Boolean(« false ») // true ! (string non vide)
Boolean(« 0 ») // true ! (string non vide)
Boolean([]) // true ! (array vide = truthy en JS)
Boolean() // true ! (objet vide = truthy en JS)
Différence Python/JS : En Python, [] et sont falsy. En JavaScript, tous les objets et arrays sont truthy, même vides. Pour tester un array vide : arr.length === 0.
Les boucles
for (let i = 0; i < 5; i++)
// for…of — itère sur les VALEURS (arrays, strings, Map, Set)
const fruits = [« pomme », « banane », « cerise »];
for (const fruit of fruits)
// for…in — itère sur les CLÉS d'un objet
const personne = ;
for (const cle in personne)
for…of vs for…in : for…of = valeurs (pour les arrays). for…in = clés/index (pour les objets). N'utilisez PAS for...in sur un array (il itère aussi sur les propriétés du prototype).
let i = 0;
while (i < 5)
// do…while — s'exécute AU MOINS une fois
let j = 10;
do while (j < 5);
// break et continue fonctionnent comme en Python
Les fonctions
function saluer(nom) {
return `Bonjour, $ !`;
}
// 2. Expression de fonction
const saluer2 = function(nom) {
return `Bonjour, $ !`;
};
// 3. Arrow function (ES6+) — syntaxe moderne recommandée
const saluer3 = (nom) => `Bonjour, $ !`;
// Arrow : si un seul paramètre, pas besoin de ()
const double = x => x * 2;
// Arrow : si plusieurs lignes, et return explicite
const somme = (a, b) => ;
const puissance = (base, exp = 2) => base ** exp;
puissance(3); // 9
puissance(3, 3); // 27
// Rest parameter (…) — comme *args en Python
const somme = (…nombres) => ;
somme(1, 2, 3); // 6
// Spread operator — décomposer un array/objet
const a = [1, 2];
const b = […a, 3, 4]; // [1, 2, 3, 4]
const obj1 = ;
const obj2 = ; //
Différence cruciale : Les arrow functions n'ont pas leur propre this. Elles héritent du this du contexte parent. C'est un avantage dans les callbacks mais un piège dans les méthodes d'objet :
this. Dans une méthode, this ne pointera pas vers l'objet. Utilisez la syntaxe courte saluer() .Les tableaux (Arrays)
// Accès
fruits[0] // « pomme »
fruits.at(–1) // « cerise » (ES2022)
fruits.length // 3
// Ajout / suppression
fruits.push(« kiwi ») // Ajoute à la fin → retourne la longueur
fruits.pop() // Supprime le dernier → retourne l'élément
fruits.unshift(« poire ») // Ajoute au début
fruits.shift() // Supprime le premier
// Recherche
fruits.includes(« banane ») // true
fruits.indexOf(« banane ») // 1 (-1 si absent)
fruits.find(f => f.length > 5) // « banane » (premier match)
fruits.findIndex(f => f === « cerise ») // 2
// Modification
fruits.splice(1, 1) // Supprime 1 élément à l'index 1
fruits.splice(1, 0, « mangue ») // Insère sans supprimer
fruits.slice(0, 2) // Copie [« pomme », »banane »] (non destructif)
// map — transforme chaque élément → nouveau array
const doubles = nombres.map(n => n * 2);
// [2, 4, 6, 8, 10]
// filter — garde les éléments qui passent le test
const pairs = nombres.filter(n => n % 2 === 0);
// [2, 4]
// reduce — accumule une valeur
const somme = nombres.reduce((acc, n) => acc + n, 0);
// 15
// forEach — exécute une action (pas de retour)
nombres.forEach(n => console.log(n));
// some / every — tests logiques
nombres.some(n => n > 4) // true (au moins un)
nombres.every(n => n > 0) // true (tous)
// Chaînage
const resultat = nombres
.filter(n => n % 2 === 0)
.map(n => n ** 2);
// [4, 16]
map/filter/reduce : Ces trois méthodes sont le cœur de la programmation fonctionnelle en JS. map = transformer, filter = sélectionner, reduce = accumuler. Elles retournent toutes un nouveau array (non destructif).
// reverse[1, 2, 3].reverse() // [3, 2, 1] (modifie l'original !)[1, 2, 3].toReversed() // [3, 2, 1] (ES2023, non destructif)
// Concaténer / Aplatir[1, 2].concat([3, 4]) // [1, 2, 3, 4][…[1, 2], …[3, 4]] // [1, 2, 3, 4] (spread)[[1, 2], [3, 4]].flat() // [1, 2, 3, 4]
Piège sort() : Sans comparateur, .sort() convertit tout en string : [10,1,21,2].sort() → [1,10,2,21]. Toujours fournir (a, b) => a – b pour les nombres.
[10,1,2].sort() → [1, 10, 2] (piège).Les objets
const personne = ;
// Accès
personne.nom // « Alice » (dot notation)
personne[« age »] // 25 (bracket notation)
personne.saluer() // « Bonjour, Alice »
// Modification
personne.email = « a@b.com »; // Ajout
delete personne.ville; // Suppression
// Vérification
« nom » in personne // true
personne.hasOwnProperty(« age ») // true
// Itérer
Object.keys(personne) // [« nom », « age », « email », « saluer »]
Object.values(personne) // [« Alice », 25, « a@b.com », ƒ]
Object.entries(personne) // [[« nom », »Alice »], [« age »,25], …]
const = personne;
console.log(nom); // « Alice »
console.log(ville); // « Inconnu » (valeur par défaut)
// Renommer pendant la destructuration
const = personne;
// Destructuration d'array
const [premier, deuxieme, …reste] = [1, 2, 3, 4, 5];
// premier = 1, deuxieme = 2, reste = [3, 4, 5]
// Dans les paramètres de fonction
const afficher = () => {
console.log(`$ a $ ans`);
};
afficher(personne);
La destructuration est partout en JS moderne. Elle simplifie l'extraction de données dans les fonctions, les imports, les réponses d'API, les props React, etc.
// ❌ Pas une copie — même référence
const ref = original;
// Shallow copy (copie superficielle)
const copie1 = ;
const copie2 = Object.assign(, original);
// ⚠️ Les objets imbriqués sont toujours des références
copie1.b.c = 99;
console.log(original.b.c); // 99 ! (modifié aussi)
// Deep copy (copie profonde)
const deep = structuredClone(original); // ES2022 ✅
const deep2 = JSON.parse(JSON.stringify(original)); // Ancien hack
Les classes (POO)
const rex = new Animal(« Rex », 5);
rex.parler() // « Rex fait du bruit. »
rex.info // « Rex (5 ans) » — getter, pas de ()
const max = new Chien(« Max », 3, « Labrador »);
max.parler() // « Max : Wouf ! »
max.race // « Labrador » (via getter)
max.#race // ❌ SyntaxError (privé)
max instanceof Chien // true
max instanceof Animal // true
this dans une classe qui extends.Asynchrone : Promises & async/await
JavaScript est single-threaded. Les opérations longues (réseau, timers, fichiers) sont asynchrones pour ne pas bloquer l'interface.
Évolution : Callbacks (ancien) → Promises (ES6) → async/await (ES2017, recommandé).
maPromise
.then(data => console.log(data))
.catch(err => console.error(err))
.finally(() => console.log(« Terminé »));
// Combinateurs
Promise.all([p1, p2]) // Toutes résolues (échoue si une échoue)
Promise.allSettled([p1, p2]) // Attend toutes (peu importe succès/échec)
Promise.race([p1, p2]) // La première terminée
Promise.any([p1, p2]) // La première résolue
// Arrow async
const getData = async () => ;
// Parallèle avec async/await
const [users, posts] = await Promise.all([
fetch(« /api/users »).then(r => r.json()),
fetch(« /api/posts »).then(r => r.json())
]);
Piège fetch() : fetch() ne rejette PAS sur un 404 ou 500. Il faut vérifier response.ok manuellement. La Promise ne rejette que sur une erreur réseau.
response.ok === false mais la Promise est résolue.Manipulation du DOM
document.querySelectorAll(« .classe ») // Tous (NodeList)
document.querySelector(« #id ») // Par ID
document.querySelector(« div > p.active ») // CSS selector
// Contenu
el.textContent = « Texte »; // Texte brut (sûr)
el.innerHTML = « HTML »; // HTML (⚠️ XSS)
// Classes
el.classList.add(« active »);
el.classList.remove(« hidden »);
el.classList.toggle(« dark »);
el.classList.contains(« active »);
// Style
el.style.color = « red »;
el.style.fontSize = « 20px »; // camelCase !
// Attributs
el.setAttribute(« data-id », « 42 »);
el.getAttribute(« href »);
el.dataset.id // « 42 » (accès data-* attributes)
btn.addEventListener(« click », (e) => );
// Événements courants :
// click, dblclick, mouseover, mouseout
// keydown, keyup, input, change
// submit, focus, blur, scroll, resize
// DOMContentLoaded, load
// Event delegation (1 listener pour N enfants)
document.querySelector(« ul »)
.addEventListener(« click », (e) => );
div.textContent = « Nouveau ! »;
div.classList.add(« card »);
parent.appendChild(div); // À la fin
parent.prepend(div); // Au début
element.after(div); // Après
div.remove(); // Suppression
Gestion des erreurs
// Lever une erreur
function diviser(a, b)
// Erreur personnalisée
class ValidationError extends Error
| Erreur | Cause | Exemple |
|---|---|---|
| ReferenceError | Variable inexistante | console.log(xyz) |
| TypeError | Mauvais type / null access | null.toString() |
| SyntaxError | Code mal formé | JSON.parse(« {« ) |
| RangeError | Hors limites | new Array(-1) |
| URIError | URI malformée | decodeURI(« % ») |
ES6+ et fonctionnalités modernes
export const PI = 3.14159;
export function carre(x)
export default function somme(a, b)
// main.js
import somme from « ./math.js »; // default
import from « ./math.js »; // named
import from « ./math.js »; // alias
import * as math from « ./math.js »; // tout
const map = new Map();
map.set(« nom », « Alice »);
map.set(42, « réponse »); // Clé = number
map.get(« nom »); // « Alice »
map.has(42); // true
map.size; // 2
map.delete(42);
for (const [key, val] of map)
// Set — valeurs uniques
const set = new Set([1, 2, 2, 3]); //
set.add(4);
set.has(2); // true
set.delete(2);
set.size; // 3
// Dédupliquer un array
const unique = […new Set([1,1,2,3,3])]; // [1, 2, 3]
Map vs Object : Map accepte n'importe quel type comme clé (objets, fonctions, etc.), préserve l'ordre d'insertion et a une propriété .size. Préférez Map pour les dictionnaires dynamiques.
| Feature | Version | Exemple |
|---|---|---|
| ?? nullish coalescing | ES2020 | null ?? « défaut » → « défaut » |
| ?. optional chaining | ES2020 | user?.address?.city |
| ??= logical assignment | ES2021 | x ??= 5 (assigne si null/undefined) |
| .at() | ES2022 | [1,2,3].at(-1) → 3 |
| #private fields | ES2022 | class |
| structuredClone() | ES2022 | Deep copy d'objets |
| .toReversed() | ES2023 | Reverse non destructif |
| .toSorted() | ES2023 | Sort non destructif |
| .with() | ES2023 | [1,2,3].with(1, 99) → [1,99,3] |
| Object.groupBy() | ES2024 | Grouper des éléments par critère |
✅ À FAIRE
• const par défaut, let si nécessaire
• Toujours ===
• Arrow functions pour les callbacks
• Destructuration pour extraire des données
• ?? au lieu de || pour les défauts
• async/await + try/catch
• Template literals au lieu de concaténation
❌ À ÉVITER
• var (hoisting imprévisible)
• == et != (coercion)
• for…in sur les arrays
• arguments (utiliser …rest)
• Mutation directe des arrays/objets
• .sort() sans comparateur sur les nombres
• Arrow functions comme méthodes d'objet
[1, 2, 3]. Le Set supprime les doublons, le spread le reconvertit en array.Cours JavaScript Complet — Des bases à l'ES2024
Pour aller plus loin : MDN Web Docs (la référence officielle).

