📚 Cours Essentiels
Préparation Examen QCM - Développement Web & Programmation
🎨 HTML & CSS
Structure HTML5
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Titre</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Contenu visible -->
</body>
</html>
Balises Sémantiques HTML5
| Balise | Usage | vs <div> |
|---|---|---|
<header> |
En-tête page/section | Sémantique |
<nav> |
Navigation principale uniquement | Sémantique |
<main> |
Contenu principal UNIQUE (1/page) | Sémantique |
<article> |
Contenu AUTONOME, réutilisable | Sémantique |
<section> |
Section thématique (avec titre) | Sémantique |
<strong> ≠ <b> | <em> ≠ <i><strong> et <em> = valeur sémantique (SEO, accessibilité)<b> et <i> = purement décoratif (déprécié)
Différence ID vs Class
| ID | Class | |
|---|---|---|
| Unicité | UNIQUE par page | RÉUTILISABLE |
| Syntaxe CSS | #nom |
.nom |
| Syntaxe HTML | id="nom" |
class="nom1 nom2" |
| Spécificité | 100 | 10 |
Box Model
box-sizing: border-box recommandé : width inclut padding + border
Unités CSS
| Unité | Type | Description |
|---|---|---|
px |
Absolue | Pixels (fixe) |
% |
Relative | Pourcentage parent |
em |
Relative | Taille relative PARENT (composé) |
rem |
Relative | Taille relative RACINE (prévisible) ✅ |
vw/vh |
Viewport | 1% largeur/hauteur viewport |
Flexbox Essentials
.container {
display: flex;
flex-direction: row; /* row | column */
justify-content: center; /* axe principal */
align-items: center; /* axe transversal */
flex-wrap: wrap;
gap: 20px;
}
justify-content: center + align-items: center
Media Queries (Mobile First)
.element { width: 100%; } /* Mobile */
@media (min-width: 768px) { /* Tablette */
.element { width: 50%; }
}
@media (min-width: 1024px) { /* Desktop */
.element { width: 33.33%; }
}
⚡ JavaScript
Variables
| Mot clé | Caractéristique | Usage |
|---|---|---|
var |
Ancien, portée fonction, hoisting | ❌ À éviter |
let |
Moderne, modifiable, portée bloc | ✅ Variables changeantes |
const |
Moderne, constante, portée bloc | ✅ Valeurs fixes |
// var - portée fonction (problematique)
var x = 10;
if (true) {
var x = 20; // Même variable !
}
console.log(x); // Résultat : 20
// let - portée bloc
let y = 10;
if (true) {
let y = 20; // Variable différente
}
console.log(y); // Résultat : 10
// const - ne peut pas être réassignée
const PI = 3.14;
PI = 3.14159; // ❌ Erreur : Assignment to constant variable
Types de Données
| Type | Exemple | typeof |
|---|---|---|
String |
"Bonjour" ou 'Bonjour' |
"string" |
Number |
42, 3.14, Infinity, NaN |
"number" |
Boolean |
true ou false |
"boolean" |
Undefined |
let x; (non initialisé) |
"undefined" |
Null |
let x = null; (vide intentionnel) |
"object" ⚠️ |
Object |
{nom: "Ali", age: 25} |
"object" |
Array |
[1, 2, 3] |
"object" |
Function |
function() {} |
"function" |
Symbol |
Symbol("id") |
"symbol" |
BigInt |
9007199254740991n |
"bigint" |
// Strings
let nom = "Alice";
console.log(typeof nom); // Résultat : "string"
// Numbers
let age = 25;
let prix = 19.99;
console.log(typeof age); // Résultat : "number"
console.log(typeof prix); // Résultat : "number"
// Boolean
let estActif = true;
console.log(typeof estActif); // Résultat : "boolean"
// Undefined - variable déclarée mais non initialisée
let x;
console.log(x); // Résultat : undefined
console.log(typeof x); // Résultat : "undefined"
// Null - valeur vide intentionnelle
let y = null;
console.log(y); // Résultat : null
console.log(typeof y); // Résultat : "object" ⚠️ (bug JS historique)
// Object
let personne = { nom: "Ali", age: 30 };
console.log(typeof personne); // Résultat : "object"
// Array (tableau)
let couleurs = ["rouge", "vert", "bleu"];
console.log(typeof couleurs); // Résultat : "object"
console.log(Array.isArray(couleurs)); // Résultat : true
// Function
function direBonjour() { return "Salut!"; }
console.log(typeof direBonjour); // Résultat : "function"
Primitifs (copie de valeur) : String, Number, Boolean, undefined, null, Symbol, BigInt
Référence (copie de référence) : Object, Array, Function
// TYPE PRIMITIF - copie de valeur
let a = 5;
let b = a; // Copie la valeur
b = 10;
console.log(a); // Résultat : 5 (inchangé)
console.log(b); // Résultat : 10
// TYPE RÉFÉRENCE - copie de référence
let obj1 = { nom: "Ali" };
let obj2 = obj1; // Copie la référence (même objet)
obj2.nom = "Sara";
console.log(obj1.nom); // Résultat : "Sara" (modifié !)
console.log(obj2.nom); // Résultat : "Sara"
// Solution pour copier un objet
let obj3 = { ...obj1 }; // Spread operator
let obj4 = JSON.parse(JSON.stringify(obj1)); // Deep copy
Opérateurs Arithmétiques
| Opérateur | Description | Exemple |
|---|---|---|
+ |
Addition / Concaténation | 5 + 3 → 8 |
- |
Soustraction | 5 - 3 → 2 |
* |
Multiplication | 5 * 3 → 15 |
/ |
Division | 6 / 2 → 3 |
% |
Modulo (reste division) | 7 % 3 → 1 |
** |
Puissance (ES6) | 2 ** 3 → 8 |
++ |
Incrémentation | let x = 5; x++ → 6 |
-- |
Décrémentation | let x = 5; x-- → 4 |
// Addition
let somme = 10 + 5;
console.log(somme); // Résultat : 15
// Concaténation (attention avec + et strings)
let texte = "Hello" + " " + "World";
console.log(texte); // Résultat : "Hello World"
console.log("5" + 3); // Résultat : "53" (concaténation !)
console.log(5 + "3"); // Résultat : "53"
// Modulo - très utile pour vérifier pair/impair
console.log(10 % 2); // Résultat : 0 (pair)
console.log(7 % 2); // Résultat : 1 (impair)
// Puissance
console.log(2 ** 10); // Résultat : 1024
// Incrémentation
let x = 5;
console.log(x++); // Affiche 5, puis x devient 6
console.log(x); // Résultat : 6
let y = 5;
console.log(++y); // Incrémente d'abord, affiche 6
Opérateurs de Comparaison
| Opérateur | Description | Exemple |
|---|---|---|
== |
Égalité valeur (avec conversion) | 5 == "5" → true |
=== |
Égalité stricte (valeur + type) | 5 === "5" → false |
!= |
Différent (avec conversion) | 5 != "5" → false |
!== |
Différent strict | 5 !== "5" → true |
>, < |
Supérieur / Inférieur | 5 > 3 → true |
>=, <= |
Supérieur ou égal / Inférieur ou égal | 5 >= 5 → true |
// == vs === (TRÈS IMPORTANT)
console.log(5 == "5"); // Résultat : true (conversion automatique)
console.log(5 === "5"); // Résultat : false (types différents)
console.log(0 == false); // Résultat : true
console.log(0 === false); // Résultat : false
console.log(null == undefined); // Résultat : true
console.log(null === undefined); // Résultat : false
// != vs !==
console.log(5 != "5"); // Résultat : false
console.log(5 !== "5"); // Résultat : true
// Comparaisons numériques
console.log(10 > 5); // Résultat : true
console.log(10 >= 10); // Résultat : true
console.log(3 < 2); // Résultat : false
// Comparaison de strings
console.log("a" < "b"); // Résultat : true
console.log("abc" < "abd"); // Résultat : true
== vs ===== : égalité valeur (conversion implicite) → 5 == "5" : true=== : égalité valeur + type (STRICTE) → 5 === "5" : false
Opérateurs Logiques
| Opérateur | Description | Exemple |
|---|---|---|
&& |
ET logique | true && false → false |
|| |
OU logique | true || false → true |
! |
NON logique | !true → false |
?? |
Coalescence nulle (ES2020) | null ?? "default" → "default" |
// && (ET) - retourne première valeur falsy ou la dernière
console.log(true && true); // Résultat : true
console.log(true && false); // Résultat : false
console.log(false && true); // Résultat : false (court-circuit)
console.log(5 && 10); // Résultat : 10
console.log(0 && 10); // Résultat : 0 (falsy)
console.log("Ali" && "Sara"); // Résultat : "Sara"
// || (OU) - retourne première valeur truthy ou la dernière
console.log(true || false); // Résultat : true
console.log(false || true); // Résultat : true
console.log(false || false); // Résultat : false
console.log(0 || 10); // Résultat : 10
console.log("" || "default"); // Résultat : "default"
// ! (NON)
console.log(!true); // Résultat : false
console.log(!false); // Résultat : true
console.log(!0); // Résultat : true
console.log(!!5); // Résultat : true (conversion en booléen)
// ?? (Nullish Coalescing) - seulement null/undefined
console.log(null ?? "default"); // Résultat : "default"
console.log(undefined ?? "default"); // Résultat : "default"
console.log(0 ?? "default"); // Résultat : 0
console.log("" ?? "default"); // Résultat : ""
&& : retourne première valeur falsy ou dernière valeur|| : retourne première valeur truthy ou dernière valeur?? : retourne première valeur définie (non null/undefined)
Structures Conditionnelles
| Structure | Syntaxe | Usage |
|---|---|---|
if / else if / else |
if (condition) {} else {} |
Conditions classiques |
switch |
switch(val) { case x: break; } |
Comparaison multiple valeurs |
Ternaire |
condition ? vrai : faux |
Conditions simples en une ligne |
let note = 75;
if (note >= 90) {
console.log("Excellent");
} else if (note >= 80) {
console.log("Très bien");
} else if (note >= 70) {
console.log("Bien");
} else if (note >= 60) {
console.log("Passable");
} else {
console.log("Insuffisant");
}
// Résultat : "Bien"
let jour = 3;
let nomJour;
switch (jour) {
case 1:
nomJour = "Lundi";
break; // Important !
case 2:
nomJour = "Mardi";
break;
case 3:
nomJour = "Mercredi";
break;
case 4:
nomJour = "Jeudi";
break;
case 5:
nomJour = "Vendredi";
break;
default:
nomJour = "Weekend";
}
console.log(nomJour); // Résultat : "Mercredi"
// Sans break (fall-through)
let x = 1;
switch (x) {
case 1:
console.log("Un");
// pas de break !
case 2:
console.log("Deux");
break;
}
// Résultat : "Un" puis "Deux" (fall-through)
let age = 20;
// if/else classique
let message;
if (age >= 18) {
message = "Majeur";
} else {
message = "Mineur";
}
// Équivalent avec ternaire
let message2 = age >= 18 ? "Majeur" : "Mineur";
console.log(message2); // Résultat : "Majeur"
// Ternaire imbriqué (à éviter pour la lisibilité)
let score = 85;
let resultat = score >= 90 ? "A" : score >= 80 ? "B" : "C";
console.log(resultat); // Résultat : "B"
Sans
break, l'exécution continue dans les cas suivants (fall-through)
Boucles
| Boucle | Syntaxe | Usage |
|---|---|---|
for |
for (let i=0; i<n; i++) {} |
Nombre d'itérations connu |
while |
while (condition) {} |
Condition d'arrêt, itérations inconnues |
do...while |
do {} while (condition) |
Au moins une exécution |
for...of |
for (let item of array) {} |
Parcourir valeurs d'un itérable |
for...in |
for (let key in obj) {} |
Parcourir clés d'un objet |
// Boucle for classique
for (let i = 0; i < 5; i++) {
console.log(i);
}
// Résultat : 0, 1, 2, 3, 4
// Parcourir un tableau
let fruits = ["pomme", "banane", "orange"];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// Résultat : "pomme", "banane", "orange"
// Boucle inversée
for (let i = 5; i > 0; i--) {
console.log(i);
}
// Résultat : 5, 4, 3, 2, 1
// while - condition vérifiée AVANT
let i = 0;
while (i < 3) {
console.log(i);
i++;
}
// Résultat : 0, 1, 2
// do...while - exécution AU MOINS une fois
let j = 10;
do {
console.log(j);
j++;
} while (j < 3);
// Résultat : 10 (exécuté une fois même si condition fausse)
// Exemple pratique : deviner un nombre
let secret = 7;
let essai = 0;
while (essai !== secret) {
essai++; // simulation
}
console.log("Trouvé !"); // Résultat : "Trouvé !"
// for...of - valeurs d'un tableau
let couleurs = ["rouge", "vert", "bleu"];
for (let couleur of couleurs) {
console.log(couleur);
}
// Résultat : "rouge", "vert", "bleu"
// for...of avec string
for (let char of "Hello") {
console.log(char);
}
// Résultat : "H", "e", "l", "l", "o"
// for...in - clés d'un objet
let personne = { nom: "Ali", age: 25, ville: "Paris" };
for (let cle in personne) {
console.log(cle + ": " + personne[cle]);
}
// Résultat : "nom: Ali", "age: 25", "ville: Paris"
// for...in sur tableau (déconseillé)
let arr = ["a", "b", "c"];
for (let index in arr) {
console.log(index); // "0", "1", "2" (strings !)
}
for...of : valeurs (tableaux, strings, Map, Set)for...in : clés/indices (objets, tableaux - évitez pour tableaux)
Fonctions
| Type | Syntaxe | Caractéristique |
|---|---|---|
| Déclaration | function nom(params) { return x; } |
Hoisted (utilisable avant déclaration) |
| Expression | const fn = function() {}; |
Non hoisted |
| Fléchée | const fn = (params) => x; |
Pas de this propre |
| IIFE | (function() { })(); |
Exécutée immédiatement |
// Déclaration (hoisted)
console.log(saluer("Ali")); // Résultat : "Bonjour Ali"
function saluer(nom) {
return "Bonjour " + nom;
}
// Expression de fonction (non hoisted)
const direAuRevoir = function(nom) {
return "Au revoir " + nom;
};
console.log(direAuRevoir("Ali")); // Résultat : "Au revoir Ali"
// Syntaxe complète
const addition = (a, b) => {
return a + b;
};
console.log(addition(5, 3)); // Résultat : 8
// Syntaxe raccourcie (return implicite)
const multiplier = (a, b) => a * b;
console.log(multiplier(4, 3)); // Résultat : 12
// Un seul paramètre - parenthèses optionnelles
const double = x => x * 2;
console.log(double(5)); // Résultat : 10
// Aucun paramètre
const direBonjour = () => "Hello!";
console.log(direBonjour()); // Résultat : "Hello!"
// Retourner un objet
const creerPersonne = (nom, age) => ({ nom, age });
console.log(creerPersonne("Ali", 25)); // Résultat : {nom: "Ali", age: 25}
// IIFE - exécutée immédiatement
(function() {
let secret = "hidden";
console.log("Exécuté immédiatement : " + secret);
})();
// Résultat : "Exécuté immédiatement : hidden"
// IIFE avec paramètre
(function(nom) {
console.log("Bonjour " + nom);
})("Ali");
// Résultat : "Bonjour Ali"
// IIFE fléchée
(() => {
console.log("IIFE fléchée");
})();
// Résultat : "IIFE fléchée"
Les arrow functions n'ont pas leur propre
this. Elles héritent du contexte parent.Ne PAS utiliser comme méthodes d'objet ou constructeurs.
// PROBLÈME avec fonction classique
const personne1 = {
nom: "Ali",
saluer: function() {
setTimeout(function() {
console.log("Bonjour " + this.nom); // this = window
}, 100);
}
};
personne1.saluer(); // Résultat : "Bonjour undefined"
// SOLUTION avec arrow function
const personne2 = {
nom: "Ali",
saluer: function() {
setTimeout(() => {
console.log("Bonjour " + this.nom); // this hérité
}, 100);
}
};
personne2.saluer(); // Résultat : "Bonjour Ali"
// ❌ NE PAS utiliser arrow function comme méthode
const personne3 = {
nom: "Ali",
saluer: () => console.log(this.nom)
};
personne3.saluer(); // Résultat : undefined
Paramètres de Fonctions
| Type | Exemple | Description |
|---|---|---|
| Par défaut | function(a = 10) {} |
Valeur si argument non fourni |
| Rest | function(...args) {} |
Nombre variable d'arguments |
| Destructuring | function({a, b}) {} |
Extraire propriétés objet |
// Paramètres par défaut
function saluer(nom = "Invité", titre = "M.") {
return "Bonjour " + titre + " " + nom;
}
console.log(saluer()); // Résultat : "Bonjour M. Invité"
console.log(saluer("Ali")); // Résultat : "Bonjour M. Ali"
console.log(saluer("Sara", "Mme")); // Résultat : "Bonjour Mme Sara"
// Avec arrow function
const calculer = (a, b = 10) => a + b;
console.log(calculer(5)); // Résultat : 15
console.log(calculer(5, 3)); // Résultat : 8
// Rest parameters - nombre variable d'arguments
function somme(...nombres) {
return nombres.reduce((acc, val) => acc + val, 0);
}
console.log(somme(1, 2, 3)); // Résultat : 6
console.log(somme(1, 2, 3, 4)); // Résultat : 10
console.log(somme(10)); // Résultat : 10
// Combiné avec autres paramètres
function logger(niveau, ...messages) {
console.log("[" + niveau + "] " + messages.join(", "));
}
logger("ERROR", "Fichier non trouvé", "Ligne 42");
// Résultat : "[ERROR] Fichier non trouvé, Ligne 42"
// Destructuring d'objet
function afficherUtilisateur({ nom, age, ville = "Inconnu" }) {
console.log(nom + ", " + age + " ans, " + ville);
}
afficherUtilisateur({ nom: "Ali", age: 25, ville: "Paris" });
// Résultat : "Ali, 25 ans, Paris"
afficherUtilisateur({ nom: "Sara", age: 30 });
// Résultat : "Sara, 30 ans, Inconnu"
// Destructuring de tableau
function premierEtDernier([premier, ...reste]) {
const dernier = reste.pop();
return { premier, dernier };
}
console.log(premierEtDernier([1, 2, 3, 4, 5]));
// Résultat : { premier: 1, dernier: 5 }
Portée (Scope)
| Portée | Description | Exemple |
|---|---|---|
| Globale | Accessible partout | Variables hors fonction |
| Fonction | Accessible dans la fonction | var dans une fonction |
| Bloc | Accessible dans le bloc | let/const dans {} |
// Variable globale
var globale = "Je suis globale";
let globale2 = "Moi aussi";
function exemple() {
// Variable de fonction (var)
var localeFonction = "Dans la fonction";
if (true) {
// Variable de bloc (let/const)
let localeBloc = "Dans le bloc";
const CONSTANTE = "Fixe";
console.log(localeFonction); // OK
console.log(localeBloc); // OK
}
console.log(localeFonction); // OK
// console.log(localeBloc); // ❌ Erreur
}
exemple();
console.log(globale); // OK
// console.log(localeFonction); // ❌ Erreur
Déclarations remontées au début de leur portée.
var : hoisted avec valeur undefinedlet/const : hoisted mais TDZ (Temporal Dead Zone)
// var - hoisted avec undefined
console.log(x); // Résultat : undefined (pas d'erreur)
var x = 5;
console.log(x); // Résultat : 5
// let/const - TDZ (Temporal Dead Zone)
// console.log(y); // ❌ ReferenceError
let y = 10;
// Function declaration - complètement hoisted
saluer(); // Résultat : "Bonjour"
function saluer() {
console.log("Bonjour");
}
// Function expression - PAS hoisted
// direAuRevoir(); // ❌ Erreur
const direAuRevoir = function() {
console.log("Au revoir");
};
Objets
| Opération | Syntaxe | Exemple |
|---|---|---|
| Création | { clé: valeur } |
{ nom: "Ali", age: 25 } |
| Accès notation point | obj.clé |
person.nom |
| Accès notation crochet | obj["clé"] |
person["nom"] |
| Ajout/Modification | obj.clé = valeur |
person.ville = "Paris" |
| Suppression | delete obj.clé |
delete person.age |
| Vérifier clé | "clé" in obj |
"nom" in person |
// Création
const personne = {
nom: "Ali",
age: 25,
ville: "Paris"
};
console.log(personne);
// Résultat : { nom: "Ali", age: 25, ville: "Paris" }
// Accès notation point
console.log(personne.nom); // Résultat : "Ali"
console.log(personne.age); // Résultat : 25
// Accès notation crochet (utile pour clés dynamiques)
console.log(personne["nom"]); // Résultat : "Ali"
let cle = "ville";
console.log(personne[cle]); // Résultat : "Paris"
// Ajout de propriété
personne.email = "ali@email.com";
console.log(personne.email); // Résultat : "ali@email.com"
// Modification
personne.age = 26;
console.log(personne.age); // Résultat : 26
// Suppression
delete personne.ville;
console.log(personne);
// Résultat : { nom: "Ali", age: 26, email: "ali@email.com" }
// Vérifier existence
console.log("nom" in personne); // Résultat : true
console.log("ville" in personne); // Résultat : false
Méthodes d'Objets Importantes
| Méthode | Description | Retourne |
|---|---|---|
Object.keys(obj) |
Liste des clés | Tableau de clés |
Object.values(obj) |
Liste des valeurs | Tableau de valeurs |
Object.entries(obj) |
Paires clé-valeur | Tableau de tableaux |
Object.assign(target, ...sources) |
Fusionne objets | Objet modifié |
Object.freeze(obj) |
Gèle l'objet | Objet non modifiable |
const personne = { nom: "Ali", age: 25, ville: "Paris" };
// Object.keys() - clés
console.log(Object.keys(personne));
// Résultat : ["nom", "age", "ville"]
// Object.values() - valeurs
console.log(Object.values(personne));
// Résultat : ["Ali", 25, "Paris"]
// Object.entries() - paires
console.log(Object.entries(personne));
// Résultat : [["nom", "Ali"], ["age", 25], ["ville", "Paris"]]
// Object.assign() - fusion
const defaults = { theme: "dark", lang: "fr" };
const userPrefs = { theme: "light" };
const config = Object.assign({}, defaults, userPrefs);
console.log(config);
// Résultat : { theme: "light", lang: "fr" }
// Object.freeze() - geler
const constantes = Object.freeze({ PI: 3.14 });
constantes.PI = 3.14159; // Ignoré silencieusement (ou erreur en strict)
console.log(constantes.PI); // Résultat : 3.14
Méthodes Strings Importantes
| Méthode | Exemple | Résultat |
|---|---|---|
length |
"Hello".length |
5 |
toUpperCase() |
"hello".toUpperCase() |
"HELLO" |
toLowerCase() |
"HELLO".toLowerCase() |
"hello" |
charAt(index) |
"Hello".charAt(0) |
"H" |
slice(start, end) |
"Hello".slice(1, 4) |
"ell" (end exclus) |
substring(start, end) |
"Hello".substring(1, 4) |
"ell" |
indexOf() |
"Hello".indexOf("l") |
2 (première occurrence) |
lastIndexOf() |
"Hello".lastIndexOf("l") |
3 (dernière occurrence) |
includes() |
"Hello".includes("el") |
true |
startsWith() |
"Hello".startsWith("He") |
true |
endsWith() |
"Hello".endsWith("lo") |
true |
split(séparateur) |
"a,b,c".split(",") |
["a", "b", "c"] |
trim() |
" hi ".trim() |
"hi" |
replace(a, b) |
"hello".replace("l", "L") |
"heLlo" (premier uniquement) |
replaceAll(a, b) |
"hello".replaceAll("l", "L") |
"heLLo" |
repeat(n) |
"ab".repeat(3) |
"ababab" |
let texte = " Hello World ";
// Length et casse
console.log(texte.length); // Résultat : 14
console.log(texte.toUpperCase()); // Résultat : " HELLO WORLD "
console.log(texte.toLowerCase()); // Résultat : " hello world "
// Trim - supprime espaces
console.log(texte.trim()); // Résultat : "Hello World"
// Accès aux caractères
console.log("Hello".charAt(0)); // Résultat : "H"
console.log("Hello"[0]); // Résultat : "H"
// Recherche
let phrase = "JavaScript est génial";
console.log(phrase.indexOf("est")); // Résultat : 11
console.log(phrase.includes("Java")); // Résultat : true
console.log(phrase.startsWith("Java")); // Résultat : true
console.log(phrase.endsWith("génial")); // Résultat : true
// Extraction
console.log("Hello World".slice(0, 5)); // Résultat : "Hello"
console.log("Hello World".slice(-5)); // Résultat : "World"
// Split et replace
let csv = "pomme,banane,orange";
let fruits = csv.split(",");
console.log(fruits); // Résultat : ["pomme", "banane", "orange"]
console.log("hello world".replace("o", "0"));
// Résultat : "hell0 world" (premier seulement)
console.log("hello world".replaceAll("o", "0"));
// Résultat : "hell0 w0rld"
Tableaux (Arrays)
| Opération | Syntaxe | Exemple |
|---|---|---|
| Création | [elem1, elem2] |
[1, 2, 3] |
| Accès | arr[index] |
arr[0] → premier élément |
| Modification | arr[index] = val |
arr[0] = 10 |
| Longueur | arr.length |
[1,2,3].length → 3 |
// Création
let nombres = [1, 2, 3, 4, 5];
let fruits = ["pomme", "banane", "orange"];
let mixte = [1, "deux", true, null];
// Accès
console.log(fruits[0]); // Résultat : "pomme"
console.log(fruits[1]); // Résultat : "banane"
console.log(fruits[-1]); // Résultat : undefined (pas Python !)
console.log(fruits.at(-1)); // Résultat : "orange" (ES2022)
// Longueur
console.log(fruits.length); // Résultat : 3
// Modification
fruits[1] = "fraise";
console.log(fruits); // Résultat : ["pomme", "fraise", "orange"]
// Ajout dynamique
fruits[3] = "kiwi";
console.log(fruits); // Résultat : ["pomme", "fraise", "orange", "kiwi"]
// Parcourir
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// Résultat : "pomme", "fraise", "orange", "kiwi"
Méthodes Arrays - Ajout/Suppression
| Méthode | Action | Modifie original ? |
|---|---|---|
push(elem) |
Ajoute à la fin | ✅ Oui |
pop() |
Supprime et retourne le dernier | ✅ Oui |
unshift(elem) |
Ajoute au début | ✅ Oui |
shift() |
Supprime et retourne le premier | ✅ Oui |
splice(index, n, ...items) |
Supprime/ajoute à un index | ✅ Oui |
slice(start, end) |
Extrait une portion | ❌ Non |
let fruits = ["pomme", "banane"];
// push - ajoute à la fin
fruits.push("orange");
console.log(fruits); // Résultat : ["pomme", "banane", "orange"]
let longueur = fruits.push("kiwi");
console.log(longueur); // Résultat : 4 (nouvelle longueur)
// pop - supprime le dernier
let dernier = fruits.pop();
console.log(dernier); // Résultat : "kiwi"
console.log(fruits); // Résultat : ["pomme", "banane", "orange"]
// unshift - ajoute au début
fruits.unshift("fraise");
console.log(fruits); // Résultat : ["fraise", "pomme", "banane", "orange"]
// shift - supprime le premier
let premier = fruits.shift();
console.log(premier); // Résultat : "fraise"
console.log(fruits); // Résultat : ["pomme", "banane", "orange"]
// slice - NE MODIFIE PAS l'original
let nombres = [1, 2, 3, 4, 5];
let extrait = nombres.slice(1, 4);
console.log(extrait); // Résultat : [2, 3, 4]
console.log(nombres); // Résultat : [1, 2, 3, 4, 5] (inchangé)
// slice avec négatifs
console.log(nombres.slice(-2)); // Résultat : [4, 5]
// splice - MODIFIE l'original
let lettres = ["a", "b", "c", "d", "e"];
let supprimes = lettres.splice(2, 2); // index 2, supprimer 2 éléments
console.log(supprimes); // Résultat : ["c", "d"]
console.log(lettres); // Résultat : ["a", "b", "e"]
// splice pour ajouter
let arr = [1, 2, 5];
arr.splice(2, 0, 3, 4); // index 2, supprimer 0, ajouter 3 et 4
console.log(arr); // Résultat : [1, 2, 3, 4, 5]
// splice pour remplacer
let arr2 = [1, 2, 3, 4];
arr2.splice(1, 2, "a", "b"); // supprime 2 et 3, ajoute a et b
console.log(arr2); // Résultat : [1, "a", "b", 4]
slice() : NE MODIFIE PAS l'original, retourne extraitsplice() : MODIFIE l'original, supprime/ajoute éléments
Méthodes Arrays - Recherche
| Méthode | Description | Retourne |
|---|---|---|
indexOf(elem) |
Premier index de l'élément | Index ou -1 |
lastIndexOf(elem) |
Dernier index de l'élément | Index ou -1 |
includes(elem) |
Vérifie présence | Boolean |
find(callback) |
Premier élément qui satisfait condition | Élément ou undefined |
findIndex(callback) |
Index du premier élément satisfaisant | Index ou -1 |
let fruits = ["pomme", "banane", "orange", "banane"];
// indexOf / lastIndexOf
console.log(fruits.indexOf("banane")); // Résultat : 1
console.log(fruits.lastIndexOf("banane")); // Résultat : 3
console.log(fruits.indexOf("kiwi")); // Résultat : -1
// includes
console.log(fruits.includes("orange")); // Résultat : true
console.log(fruits.includes("kiwi")); // Résultat : false
// find - trouver un élément selon condition
let nombres = [5, 12, 8, 130, 44];
let premierGrand = nombres.find(n => n > 10);
console.log(premierGrand); // Résultat : 12
// find avec objets
let utilisateurs = [
{ id: 1, nom: "Ali" },
{ id: 2, nom: "Sara" },
{ id: 3, nom: "Omar" }
];
let user = utilisateurs.find(u => u.id === 2);
console.log(user); // Résultat : { id: 2, nom: "Sara" }
// findIndex
let index = utilisateurs.findIndex(u => u.nom === "Omar");
console.log(index); // Résultat : 2
Méthodes Arrays - Transformation
| Méthode | Action | Modifie original ? |
|---|---|---|
map(callback) |
Transforme chaque élément | ❌ Non (nouveau tableau) |
filter(callback) |
Filtre selon condition | ❌ Non (nouveau tableau) |
reduce(callback, init) |
Réduit à une seule valeur | ❌ Non |
sort(compareFn) |
Trie le tableau | ✅ Oui |
reverse() |
Inverse l'ordre | ✅ Oui |
flat(depth) |
Aplatit tableau imbriqué | ❌ Non |
flatMap(callback) |
map + flat | ❌ Non |
let nombres = [1, 2, 3, 4, 5];
// Doubler chaque nombre
let doubles = nombres.map(n => n * 2);
console.log(doubles); // Résultat : [2, 4, 6, 8, 10]
console.log(nombres); // Résultat : [1, 2, 3, 4, 5] (inchangé)
// Extraire une propriété
let users = [
{ nom: "Ali", age: 25 },
{ nom: "Sara", age: 30 },
{ nom: "Omar", age: 20 }
];
let noms = users.map(u => u.nom);
console.log(noms); // Résultat : ["Ali", "Sara", "Omar"]
// Transformer en HTML
let items = ["Pommes", "Bananes", "Oranges"];
let html = items.map(item => `${item} `);
console.log(html);
// Résultat : ["Pommes ", "Bananes ", "Oranges "]
let nombres = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Nombres pairs
let pairs = nombres.filter(n => n % 2 === 0);
console.log(pairs); // Résultat : [2, 4, 6, 8, 10]
// Nombres > 5
let grands = nombres.filter(n => n > 5);
console.log(grands); // Résultat : [6, 7, 8, 9, 10]
// Filtrer des objets
let produits = [
{ nom: "Laptop", prix: 1000, stock: 5 },
{ nom: "Phone", prix: 500, stock: 0 },
{ nom: "Tablet", prix: 300, stock: 10 }
];
let enStock = produits.filter(p => p.stock > 0);
console.log(enStock);
// Résultat : [{ nom: "Laptop", prix: 1000, stock: 5 }, { nom: "Tablet", prix: 300, stock: 10 }]
let chers = produits.filter(p => p.prix >= 500);
console.log(chers);
// Résultat : [{ nom: "Laptop", prix: 1000, stock: 5 }, { nom: "Phone", prix: 500, stock: 0 }]
let nombres = [1, 2, 3, 4, 5];
// Somme
let somme = nombres.reduce((acc, n) => acc + n, 0);
console.log(somme); // Résultat : 15
// Produit
let produit = nombres.reduce((acc, n) => acc * n, 1);
console.log(produit); // Résultat : 120
// Max
let max = nombres.reduce((acc, n) => n > acc ? n : acc);
console.log(max); // Résultat : 5
// Grouper par propriété
let personnes = [
{ nom: "Ali", categorie: "A" },
{ nom: "Sara", categorie: "B" },
{ nom: "Omar", categorie: "A" }
];
let groupes = personnes.reduce((acc, p) => {
if (!acc[p.categorie]) acc[p.categorie] = [];
acc[p.categorie].push(p.nom);
return acc;
}, {});
console.log(groupes);
// Résultat : { A: ["Ali", "Omar"], B: ["Sara"] }
// ATTENTION : sort modifie l'original !
let fruits = ["banane", "pomme", "orange", "kiwi"];
fruits.sort();
console.log(fruits); // Résultat : ["banane", "kiwi", "orange", "pomme"]
// Sort avec nombres (PIÈGE)
let nombres = [10, 2, 100, 5];
nombres.sort(); // Tri alphabétique !
console.log(nombres); // Résultat : [10, 100, 2, 5] ❌
// Sort correct avec nombres
nombres.sort((a, b) => a - b);
console.log(nombres); // Résultat : [2, 5, 10, 100] ✅
// Tri décroissant
nombres.sort((a, b) => b - a);
console.log(nombres); // Résultat : [100, 10, 5, 2]
// Trier des objets
let users = [
{ nom: "Ali", age: 25 },
{ nom: "Sara", age: 30 },
{ nom: "Omar", age: 20 }
];
users.sort((a, b) => a.age - b.age);
console.log(users);
// Résultat : [{ nom: "Omar", age: 20 }, { nom: "Ali", age: 25 }, { nom: "Sara", age: 30 }]
Méthodes Arrays - Itération
| Méthode | Description | Retourne |
|---|---|---|
forEach(callback) |
Exécute fonction pour chaque élément | undefined |
every(callback) |
Tous les éléments satisfont condition ? | Boolean |
some(callback) |
Au moins un élément satisfait condition ? | Boolean |
let nombres = [1, 2, 3, 4, 5];
// forEach - itération simple
nombres.forEach((n, index) => {
console.log(`Index ${index}: ${n}`);
});
// Résultat : "Index 0: 1", "Index 1: 2", ...
// every - TOUS doivent satisfaire
let tousPositifs = nombres.every(n => n > 0);
console.log(tousPositifs); // Résultat : true
let tousGrands = nombres.every(n => n > 3);
console.log(tousGrands); // Résultat : false
// some - AU MOINS UN doit satisfaire
let auMoinsUnPair = nombres.some(n => n % 2 === 0);
console.log(auMoinsUnPair); // Résultat : true
let auMoinsUnGrand = nombres.some(n => n > 10);
console.log(auMoinsUnGrand); // Résultat : false
map : retourne nouveau tableau (utilisable en chaîne)forEach : ne retourne rien (pour effets de bord)
Spread Operator (...)
| Usage | Exemple |
|---|---|
| Copier un tableau | [...arr] |
| Fusionner tableaux | [...arr1, ...arr2] |
| Copier un objet | {...obj} |
| Fusionner objets | {...obj1, ...obj2} |
| Arguments fonction | Math.max(...arr) |
// Copier un tableau (shallow copy)
let original = [1, 2, 3];
let copie = [...original];
copie.push(4);
console.log(original); // Résultat : [1, 2, 3]
console.log(copie); // Résultat : [1, 2, 3, 4]
// Fusionner des tableaux
let arr1 = [1, 2];
let arr2 = [3, 4];
let fusion = [...arr1, ...arr2];
console.log(fusion); // Résultat : [1, 2, 3, 4]
// Copier un objet
let personne = { nom: "Ali", age: 25 };
let copiePersonne = { ...personne };
copiePersonne.age = 30;
console.log(personne.age); // Résultat : 25 (inchangé)
console.log(copiePersonne.age); // Résultat : 30
// Fusionner avec override
let defaults = { theme: "dark", lang: "fr" };
let userPrefs = { theme: "light" };
let config = { ...defaults, ...userPrefs };
console.log(config);
// Résultat : { theme: "light", lang: "fr" }
// Passer des arguments
let nombres = [5, 1, 9, 3];
console.log(Math.max(...nombres)); // Résultat : 9
console.log(Math.min(...nombres)); // Résultat : 1
// Dans les appels de fonction
function somme(a, b, c) {
return a + b + c;
}
let nums = [1, 2, 3];
console.log(somme(...nums)); // Résultat : 6
Destructuring
| Type | Syntaxe | Exemple |
|---|---|---|
| Tableau | [a, b] = arr |
const [a, b] = [1, 2] |
| Objet | {a, b} = obj |
const {nom, age} = person |
| Valeur par défaut | {a = 10} |
const {x = 5} = {} |
| Renommage | {a: nouveauNom} |
const {nom: n} = person |
| Rest | [a, ...reste] |
const [premier, ...autres] = arr |
// Destructuring simple
let [a, b] = [1, 2];
console.log(a); // Résultat : 1
console.log(b); // Résultat : 2
// Ignorer des éléments
let [x, , z] = [1, 2, 3];
console.log(x); // Résultat : 1
console.log(z); // Résultat : 3
// Valeur par défaut
let [p, q, r = 3] = [1, 2];
console.log(r); // Résultat : 3
// Rest elements
let [premier, ...reste] = [1, 2, 3, 4, 5];
console.log(premier); // Résultat : 1
console.log(reste); // Résultat : [2, 3, 4, 5]
// Échanger des variables
let m = 1, n = 2;
[m, n] = [n, m];
console.log(m); // Résultat : 2
console.log(n); // Résultat : 1
let personne = { nom: "Ali", age: 25, ville: "Paris" };
// Destructuring simple
let { nom, age } = personne;
console.log(nom); // Résultat : "Ali"
console.log(age); // Résultat : 25
// Renommage
let { nom: prenom } = personne;
console.log(prenom); // Résultat : "Ali"
// Valeur par défaut
let { nom: n, pays = "France" } = personne;
console.log(n); // Résultat : "Ali"
console.log(pays); // Résultat : "France"
// Rest properties
let { nom: name, ...autres } = personne;
console.log(name); // Résultat : "Ali"
console.log(autres); // Résultat : { age: 25, ville: "Paris" }
// Destructuring imbriqué
let user = {
id: 1,
info: { nom: "Sara", adresse: { ville: "Lyon" } }
};
let { info: { nom: userName, adresse: { ville } } } = user;
console.log(userName); // Résultat : "Sara"
console.log(ville); // Résultat : "Lyon"
Template Literals
| Syntaxe | Description | Exemple |
|---|---|---|
`text ${var}` |
Interpolation de variables | `Bonjour ${nom}` |
`ligne1 |
Chaînes multi-lignes | Texte sur plusieurs lignes |
tag`texte` |
Tagged templates | Fonction personnalisée |
let nom = "Ali";
let age = 25;
// Interpolation
let message = `Bonjour, je m'appelle ${nom} et j'ai ${age} ans.`;
console.log(message);
// Résultat : "Bonjour, je m'appelle Ali et j'ai 25 ans."
// Expressions
let a = 5, b = 3;
console.log(`${a} + ${b} = ${a + b}`);
// Résultat : "5 + 3 = 8"
// Multi-lignes
let poeme = `Roses are red,
Violets are blue,
JavaScript is awesome,
And so are you!`;
console.log(poeme);
// Résultat : le poème sur plusieurs lignes
// Dans une fonction
function saluer(nom, heure) {
return `Bonjour ${nom}, il est ${heure}h`;
}
console.log(saluer("Sara", 14));
// Résultat : "Bonjour Sara, il est 14h"
// Tagged template (avancé)
function upper(strings, ...values) {
return strings.reduce((result, str, i) =>
result + str + (values[i] ? values[i].toUpperCase() : ''), '');
}
let resultat = upper`Hello ${nom}!`;
console.log(resultat); // Résultat : "Hello ALI!"
Classes
| Élément | Syntaxe | Description |
|---|---|---|
| Déclaration | class Nom {} |
Définit une classe |
| Constructeur | constructor() {} |
Initialise l'instance |
| Méthode | methode() {} |
Fonction de la classe |
| Héritage | class Enfant extends Parent {} |
Hérite de Parent |
| super() | super(args) |
Appelle constructeur parent |
| Static | static methode() {} |
Méthode de classe (pas d'instance) |
| Getter | get prop() {} |
Accès comme propriété |
| Setter | set prop(val) {} |
Modification comme propriété |
class Personne {
// Constructeur
constructor(nom, age) {
this.nom = nom;
this.age = age;
}
// Méthode
sePresenter() {
return `Je suis ${this.nom}, j'ai ${this.age} ans`;
}
// Getter
get majeur() {
return this.age >= 18;
}
// Setter
set anniversaire(val) {
this.age = val;
}
}
// Instanciation
let ali = new Personne("Ali", 25);
console.log(ali.sePresenter()); // Résultat : "Je suis Ali, j'ai 25 ans"
console.log(ali.majeur); // Résultat : true
ali.anniversaire = 26;
console.log(ali.age); // Résultat : 26
class Animal {
constructor(nom) {
this.nom = nom;
}
parler() {
return "Son d'animal";
}
}
class Chien extends Animal {
constructor(nom, race) {
super(nom); // Appel du constructeur parent
this.race = race;
}
parler() {
return `${this.nom} dit: Wouf!`;
}
}
class Chat extends Animal {
parler() {
return `${this.nom} dit: Miaou!`;
}
}
let rex = new Chien("Rex", "Berger");
let minou = new Chat("Minou");
console.log(rex.parler()); // Résultat : "Rex dit: Wouf!"
console.log(minou.parler()); // Résultat : "Minou dit: Miaou!"
console.log(rex.race); // Résultat : "Berger"
class MathUtils {
static PI = 3.14159;
static carre(x) {
return x * x;
}
static cube(x) {
return x * x * x;
}
}
// Utilisation sans instanciation
console.log(MathUtils.PI); // Résultat : 3.14159
console.log(MathUtils.carre(5)); // Résultat : 25
console.log(MathUtils.cube(3)); // Résultat : 27
// ❌ Ne fonctionne pas sur une instance
let utils = new MathUtils();
// console.log(utils.carre(5)); // Erreur
Modules ES6
| Syntaxe | Description |
|---|---|
export const x = 1; |
Export nommé |
export default fn; |
Export par défaut |
import { x } from 'module'; |
Import nommé |
import fn from 'module'; |
Import par défaut |
import * as mod from 'module'; |
Import tout |
// ===== Fichier: math.js =====
// Export nommé
export const PI = 3.14159;
export function addition(a, b) {
return a + b;
}
export function multiplication(a, b) {
return a * b;
}
// Export par défaut (un seul par fichier)
export default class Calculatrice {
constructor() {
this.resultat = 0;
}
add(n) { this.resultat += n; }
}
// ===== Fichier: main.js =====
// Import par défaut
import Calculatrice from './math.js';
// Import nommé
import { PI, addition } from './math.js';
// Import avec renommage
import { multiplication as multi } from './math.js';
// Import tout
import * as MathModule from './math.js';
// Utilisation
console.log(PI); // Résultat : 3.14159
console.log(addition(2, 3)); // Résultat : 5
console.log(MathModule.PI); // Résultat : 3.14159
let calc = new Calculatrice();
calc.add(10);
console.log(calc.resultat); // Résultat : 10
Promesses (Promises)
| Méthode | Description |
|---|---|
new Promise((resolve, reject) => {}) |
Créer une promesse |
.then(result => {}) |
Succès |
.catch(error => {}) |
Erreur |
.finally(() => {}) |
Toujours exécuté |
Promise.all([p1, p2]) |
Toutes doivent réussir |
Promise.race([p1, p2]) |
Première résolue/rejetée |
Promise.allSettled([p1, p2]) |
Attend toutes les promesses |
Promise.any([p1, p2]) |
Première résolue |
// Créer une promesse
const simulerAPI = new Promise((resolve, reject) => {
const succes = true;
setTimeout(() => {
if (succes) {
resolve({ nom: "Ali", age: 25 });
} else {
reject("Erreur de connexion");
}
}, 1000);
});
// Utiliser la promesse
simulerAPI
.then(data => {
console.log("Succès:", data);
return data.nom;
})
.then(nom => {
console.log("Nom:", nom);
})
.catch(erreur => {
console.error("Erreur:", erreur);
})
.finally(() => {
console.log("Terminé");
});
// Après 1 seconde :
// Résultat : "Succès: { nom: "Ali", age: 25 }"
// Résultat : "Nom: Ali"
// Résultat : "Terminé"
let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
let p3 = new Promise(resolve => setTimeout(() => resolve(3), 1000));
// Promise.all - attend que TOUTES réussissent
Promise.all([p1, p2, p3])
.then(resultats => console.log(resultats));
// Après 1 seconde : Résultat : [1, 2, 3]
// Promise.race - première terminée gagne
let rapide = Promise.resolve("rapide");
let lent = new Promise(r => setTimeout(() => r("lent"), 1000));
Promise.race([rapide, lent])
.then(gagnant => console.log(gagnant));
// Résultat : "rapide"
// Promise.allSettled - attend toutes (même les échecs)
let succes = Promise.resolve("OK");
let echec = Promise.reject("KO");
Promise.allSettled([succes, echec])
.then(resultats => console.log(resultats));
// Résultat : [
// { status: "fulfilled", value: "OK" },
// { status: "rejected", reason: "KO" }
// ]
Async / Await
| Syntaxe | Description |
|---|---|
async function fn() {} |
Déclare fonction asynchrone |
await promise |
Attend résolution de la promesse |
try { await ... } catch(e) {} |
Gestion d'erreurs avec async/await |
// Fonction asynchrone
async function obtenirDonnees() {
// Simuler un délai
const delai = ms => new Promise(r => setTimeout(r, ms));
console.log("Début");
await delai(1000);
console.log("Après 1 seconde");
return "Terminé";
}
obtenirDonnees().then(result => console.log(result));
// Résultat : "Début" (immédiat)
// Résultat : "Après 1 seconde" (après 1s)
// Résultat : "Terminé" (après 1s)
async function fetchUser(id) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const user = await response.json();
return user;
} catch (error) {
console.error("Erreur:", error.message);
return null;
}
}
// Utilisation
async function main() {
const user = await fetchUser(1);
if (user) {
console.log("Utilisateur:", user.nom);
}
}
// Appels parallèles avec async/await
async function fetchAll() {
const [users, posts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
]);
console.log(users, posts);
}
await ne peut être utilisé que dans une fonction asyncUne fonction
async retourne toujours une Promise
DOM Manipulation
| Méthode | Retourne |
|---|---|
getElementById('id') |
1 élément |
getElementsByClassName('class') |
HTMLCollection (live) |
getElementsByTagName('tag') |
HTMLCollection (live) |
querySelector('selector') |
1er élément correspondant |
querySelectorAll('selector') |
NodeList (statique) |
// HTML:
//
// Titre
// Paragraphe 1
// Paragraphe 2
//
// getElementById - un seul élément
const header = document.getElementById("header");
console.log(header.id); // Résultat : "header"
// querySelector - premier élément correspondant
const premierParagraphe = document.querySelector(".text");
console.log(premierParagraphe.textContent);
// Résultat : "Paragraphe 1"
// querySelectorAll - tous les éléments (NodeList)
const tousLesParagraphes = document.querySelectorAll(".text");
tousLesParagraphes.forEach(p => console.log(p.textContent));
// Résultat : "Paragraphe 1", "Paragraphe 2"
// getElementsByClassName - HTMLCollection (live)
const textes = document.getElementsByClassName("text");
console.log(textes.length); // Résultat : 2
// Sélecteurs CSS complexes
const special = document.querySelector("#header > p.text:first-child");
const inputs = document.querySelectorAll("input[type='text']");
DOM - Modification
| Propriété/Méthode | Description |
|---|---|
element.innerHTML |
Contenu HTML (interprète les balises) |
element.textContent |
Texte brut (sécurisé) |
element.setAttribute('attr', 'val') |
Définit un attribut |
element.getAttribute('attr') |
Récupère un attribut |
element.classList.add('class') |
Ajoute une classe |
element.classList.remove('class') |
Supprime une classe |
element.classList.toggle('class') |
Ajoute/Supprime une classe |
element.classList.contains('class') |
Vérifie présence classe |
element.style.property = 'value' |
Modifie style inline |
const div = document.querySelector("#container");
// innerHTML vs textContent
div.innerHTML = "Gras"; // Interprète le HTML
div.textContent = "Gras"; // Affiche tel quel
// Attributs
div.setAttribute("data-id", "123");
console.log(div.getAttribute("data-id")); // Résultat : "123"
// Classes
div.classList.add("active", "visible");
div.classList.remove("hidden");
div.classList.toggle("highlight");
console.log(div.classList.contains("active")); // Résultat : true/false
// Style inline
div.style.backgroundColor = "blue";
div.style.fontSize = "20px";
div.style.display = "none";
// Dataset (data-attributes)
//
console.log(div.dataset.userId); // Résultat : "1"
console.log(div.dataset.name); // Résultat : "ali"
div.dataset.role = "admin";
Différence innerHTML vs textContent :
innerHTML : interprète le HTML (risque XSS)
textContent : texte brut (plus sûr)
DOM - Création/Suppression
Méthode
Description
document.createElement('tag')
Crée un élément
parent.appendChild(child)
Ajoute à la fin
parent.insertBefore(new, ref)
Insère avant un élément
parent.removeChild(child)
Supprime un enfant
element.remove()
Supprime l'élément lui-même
element.replaceChild(new, old)
Remplace un enfant
element.cloneNode(true)
Clone l'élément (deep)
Exemple - Création d'éléments :
// Créer un élément
const nouveauParagraphe = document.createElement("p");
nouveauParagraphe.textContent = "Nouveau paragraphe";
nouveauParagraphe.classList.add("text");
// Ajouter au DOM
const container = document.querySelector("#container");
container.appendChild(nouveauParagraphe);
// Créer plusieurs éléments
const ul = document.createElement("ul");
["Ali", "Sara", "Omar"].forEach(nom => {
const li = document.createElement("li");
li.textContent = nom;
ul.appendChild(li);
});
document.body.appendChild(ul);
// Insérer avant un élément
const reference = document.querySelector("#reference");
const nouveau = document.createElement("div");
nouveau.textContent = "Inséré avant";
reference.parentNode.insertBefore(nouveau, reference);
// insertAdjacentHTML (plus performant)
container.insertAdjacentHTML("beforeend", "Ajouté");
// Positions: beforebegin, afterbegin, beforeend, afterend
// Supprimer
const element = document.querySelector("#toRemove");
element.remove(); // Moderne
// element.parentNode.removeChild(element); // Ancien
// Cloner
const clone = element.cloneNode(true); // true = deep clone
Événements
Syntaxe
Description
element.addEventListener('event', fn)
Ajoute un écouteur
element.removeEventListener('event', fn)
Supprime un écouteur
element.onevent = fn
Propriété (remplace existant)
Exemple - Gestionnaires d'événements :
const btn = document.querySelector("#monBtn");
// addEventListener (recommandé)
btn.addEventListener("click", function(event) {
console.log("Bouton cliqué!");
console.log(event.target); // Élément cliqué
});
// Arrow function
btn.addEventListener("click", (e) => {
console.log("Click avec arrow");
});
// Fonction nommée (pour pouvoir supprimer)
function handleClick(e) {
console.log("Handler nommé");
}
btn.addEventListener("click", handleClick);
btn.removeEventListener("click", handleClick); // Supprime l'écouteur
// Propriété onevent (ancien, écrase les autres)
btn.onclick = function() {
console.log("onclick");
};
// Options avancées
btn.addEventListener("click", handler, {
once: true, // Exécuté une seule fois
capture: false, // Phase de capture
passive: true // Optimisation scroll
});
Événements Courants
Catégorie
Événements
Souris
click, dblclick, mouseenter, mouseleave, mousemove
Clavier
keydown, keyup, keypress (déprécié)
Formulaire
submit, input, change, focus, blur
Document
DOMContentLoaded, load, scroll, resize
Exemple - Événements courants :
// Événements souris
element.addEventListener("click", (e) => {
console.log(e.clientX, e.clientY); // Position
});
element.addEventListener("mouseenter", () => {
element.style.background = "yellow";
});
element.addEventListener("mouseleave", () => {
element.style.background = "";
});
// Événements clavier
document.addEventListener("keydown", (e) => {
console.log(e.key); // "Enter", "a", "Escape"...
console.log(e.code); // "Enter", "KeyA", "Escape"...
console.log(e.ctrlKey); // true si Ctrl enfoncé
if (e.key === "Escape") {
closeModal();
}
});
// Événements formulaire
const input = document.querySelector("input");
input.addEventListener("input", (e) => {
console.log(e.target.value); // Valeur actuelle
});
input.addEventListener("focus", () => {
console.log("Focus gagné");
});
input.addEventListener("blur", () => {
console.log("Focus perdu");
});
// Événements document
document.addEventListener("DOMContentLoaded", () => {
console.log("DOM prêt");
});
window.addEventListener("load", () => {
console.log("Tout chargé (images...)");
});
window.addEventListener("scroll", () => {
console.log(window.scrollY);
});
Objet Event
Propriété/Méthode
Description
event.target
Élément qui a déclenché l'événement
event.currentTarget
Élément avec l'écouteur
event.preventDefault()
Annule comportement par défaut
event.stopPropagation()
Arrête la propagation
event.type
Type de l'événement
event.key
Touche pressée (keyboard)
event.clientX / clientY
Position souris
Exemple - Objet Event :
// target vs currentTarget
const ul = document.querySelector("ul");
ul.addEventListener("click", (e) => {
console.log("target:", e.target.tagName); // LI (cliqué)
console.log("currentTarget:", e.currentTarget.tagName); // UL
});
// preventDefault - annuler comportement par défaut
const form = document.querySelector("form");
form.addEventListener("submit", (e) => {
e.preventDefault(); // Empêche l'envoi du formulaire
console.log("Formulaire non envoyé");
});
const lien = document.querySelector("a");
lien.addEventListener("click", (e) => {
e.preventDefault(); // Empêche la navigation
});
// stopPropagation - arrêter la propagation
const parent = document.querySelector("#parent");
const enfant = document.querySelector("#enfant");
parent.addEventListener("click", () => {
console.log("Parent cliqué");
});
enfant.addEventListener("click", (e) => {
e.stopPropagation(); // Le parent ne recevra pas l'événement
console.log("Enfant cliqué");
});
// Informations clavier
document.addEventListener("keydown", (e) => {
console.log("Touche:", e.key);
console.log("Code:", e.code);
console.log("Modificateurs:", {
ctrl: e.ctrlKey,
shift: e.shiftKey,
alt: e.altKey,
meta: e.metaKey
});
});
⚠️ target vs currentTarget :
target : élément réellement cliqué (peut être un enfant)
currentTarget : élément sur lequel l'écouteur est attaché
Local Storage / Session Storage
Méthode
Description
localStorage.setItem('key', 'value')
Stocker une valeur
localStorage.getItem('key')
Récupérer une valeur
localStorage.removeItem('key')
Supprimer une clé
localStorage.clear()
Tout supprimer
Exemple - Local Storage :
// Stocker des données simples
localStorage.setItem("username", "Ali");
localStorage.setItem("theme", "dark");
// Récupérer
console.log(localStorage.getItem("username")); // Résultat : "Ali"
console.log(localStorage.getItem("inexistant")); // Résultat : null
// Supprimer une clé
localStorage.removeItem("theme");
// Vider tout
localStorage.clear();
// Stocker des objets (JSON obligatoire)
const user = { nom: "Ali", age: 25, preferences: { theme: "dark" } };
localStorage.setItem("user", JSON.stringify(user));
// Récupérer un objet
const savedUser = JSON.parse(localStorage.getItem("user"));
console.log(savedUser.nom); // Résultat : "Ali"
// Vérifier si une clé existe
if (localStorage.getItem("token")) {
console.log("Utilisateur connecté");
}
// Nombre d'éléments stockés
console.log(localStorage.length);
// Parcourir toutes les clés
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
console.log(key, localStorage.getItem(key));
}
Différence localStorage vs sessionStorage :
localStorage : persiste après fermeture du navigateur
sessionStorage : effacé à la fermeture de l'onglet
Stockage limité aux chaînes de caractères (utiliser JSON.stringify/parse pour objets)
JSON
Méthode
Description
Exemple
JSON.stringify(obj)
Objet → Chaîne JSON
JSON.stringify({a: 1}) → '{"a":1}'
JSON.parse(str)
Chaîne JSON → Objet
JSON.parse('{"a":1}') → {a: 1}
Exemple - JSON :
// Objet JavaScript → JSON
const personne = {
nom: "Ali",
age: 25,
actif: true,
hobbies: ["lecture", "sport"]
};
const jsonStr = JSON.stringify(personne);
console.log(jsonStr);
// Résultat : '{"nom":"Ali","age":25,"actif":true,"hobbies":["lecture","sport"]}'
// JSON → Objet JavaScript
const obj = JSON.parse(jsonStr);
console.log(obj.nom); // Résultat : "Ali"
console.log(obj.age); // Résultat : 25
// Formatage (indentation)
const pretty = JSON.stringify(personne, null, 2);
console.log(pretty);
// Résultat :
// {
// "nom": "Ali",
// "age": 25,
// "actif": true,
// "hobbies": ["lecture", "sport"]
// }
// Filtrer les propriétés
const filtré = JSON.stringify(personne, ["nom", "age"]);
console.log(filtré); // Résultat : '{"nom":"Ali","age":25}'
// Gestion des erreurs
try {
const data = JSON.parse('invalide');
} catch (e) {
console.error("JSON invalide:", e.message);
}
// Valeurs non supportées
const obj2 = {
fn: function() {}, // Ignorée
undef: undefined, // Ignorée
date: new Date() // Convertie en string
};
console.log(JSON.stringify(obj2));
// Résultat : '{"date":"2024-..."}'
Fetch API
Syntaxe
Description
fetch('url')
Requête GET simple
fetch('url', options)
Requête avec options
response.json()
Parse réponse en JSON
response.text()
Récupère texte brut
response.ok
True si statut 200-299
response.status
Code HTTP (200, 404...)
Exemple - Fetch GET :
// GET simple
fetch('https://jsonplaceholder.typicode.com/users/1')
.then(response => {
if (!response.ok) {
throw new Error('HTTP ' + response.status);
}
return response.json();
})
.then(user => {
console.log(user.name);
console.log(user.email);
})
.catch(error => {
console.error('Erreur:', error);
});
// GET avec async/await
async function getUser(id) {
try {
const response = await fetch(
`https://jsonplaceholder.typicode.com/users/${id}`
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const user = await response.json();
return user;
} catch (error) {
console.error('Erreur:', error);
return null;
}
}
const user = await getUser(1);
console.log(user.name); // Résultat : "Leanne Graham"
Exemple - Fetch POST :
// POST avec données JSON
async function createUser(userData) {
const response = await fetch(
'https://jsonplaceholder.typicode.com/users',
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(userData)
}
);
const newUser = await response.json();
return newUser;
}
const result = await createUser({
name: 'Ali',
email: 'ali@email.com'
});
console.log(result.id); // Résultat : 11 (nouvel ID)
// PUT (mise à jour complète)
async function updateUser(id, userData) {
const response = await fetch(
`https://jsonplaceholder.typicode.com/users/${id}`,
{
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
}
);
return response.json();
}
// DELETE
async function deleteUser(id) {
const response = await fetch(
`https://jsonplaceholder.typicode.com/users/${id}`,
{ method: 'DELETE' }
);
return response.ok; // true si succès
}
Gestion d'Erreurs
Syntaxe
Description
try { ... } catch(e) { ... }
Capturer les erreurs
try { ... } finally { ... }
finally toujours exécuté
throw new Error('message')
Lancer une erreur
error.message
Message de l'erreur
error.name
Nom du type d'erreur
Exemple - try/catch/finally :
// try/catch simple
try {
const resultat = JSON.parse('invalide');
} catch (error) {
console.log(error.name); // Résultat : "SyntaxError"
console.log(error.message); // Résultat : "Unexpected token..."
}
// Avec finally
let connection = null;
try {
connection = openConnection();
// ... opérations
} catch (error) {
console.error("Erreur:", error.message);
} finally {
if (connection) {
connection.close(); // Toujours exécuté
}
}
// Lancer une erreur personnalisée
function diviser(a, b) {
if (b === 0) {
throw new Error("Division par zéro impossible");
}
return a / b;
}
try {
diviser(10, 0);
} catch (e) {
console.log(e.message); // Résultat : "Division par zéro impossible"
}
// Types d'erreurs
throw new TypeError("Mauvais type");
throw new RangeError("Valeur hors limites");
throw new ReferenceError("Variable non définie");
throw new SyntaxError("Syntaxe invalide");
// Erreur personnalisée
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
throw new ValidationError("Email invalide", "email");
Expressions Régulières (Regex)
Syntaxe
Description
/pattern/flags
Littéral regex
new RegExp('pattern', 'flags')
Constructeur
regex.test(str)
Teste si correspond → Boolean
regex.exec(str)
Retourne correspondances
str.match(regex)
Retourne correspondances
str.replace(regex, 'new')
Remplace correspondances
Exemple - Regex :
// Création
const regex1 = /hello/i; // Littéral
const regex2 = new RegExp("hello", "i"); // Constructeur
// test - retourne boolean
console.log(/hello/.test("hello world")); // Résultat : true
console.log(/hello/.test("world")); // Résultat : false
// match - retourne correspondances ou null
const str = "Mon numéro: 0612345678 et 0698765432";
const matches = str.match(/\d{10}/g);
console.log(matches); // Résultat : ["0612345678", "0698765432"]
// exec - une correspondance à la fois
const regex = /\d+/g;
let match;
while ((match = regex.exec("123 abc 456")) !== null) {
console.log(match[0], "à l'index", match.index);
}
// Résultat : "123 à l'index 0", "456 à l'index 8"
// replace
const texte = "Hello World";
console.log(texte.replace(/o/g, "0")); // Résultat : "Hell0 W0rld"
// search - index de la première correspondance
console.log("hello world".search(/world/)); // Résultat : 6
// split avec regex
console.log("a1b2c3d".split(/\d/)); // Résultat : ["a", "b", "c", "d"]
Exemple - Patterns courants :
// Email
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test("test@email.com")); // Résultat : true
// Numéro de téléphone français
const telRegex = /^0[1-9]\d{8}$/;
console.log(telRegex.test("0612345678")); // Résultat : true
// Code postal
const cpRegex = /^\d{5}$/;
console.log(cpRegex.test("75001")); // Résultat : true
// URL
const urlRegex = /^https?:\/\/[^\s]+$/;
// Mot de passe (min 8 chars, 1 maj, 1 min, 1 chiffre)
const pwdRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
console.log(pwdRegex.test("Password1")); // Résultat : true
// Extraire données
const phrase = "Prix: 50€, Quantité: 3";
const prix = phrase.match(/\d+/g);
console.log(prix); // Résultat : ["50", "3"]
// Nettoyer une chaîne
const dirty = " Hello World ";
const clean = dirty.replace(/\s+/g, " ").trim();
console.log(clean); // Résultat : "Hello World"
Drapeaux Regex
Drapeau
Description
g
Global (toutes les correspondances)
i
Insensible à la casse
m
Multiligne
s
Dotall (. match newline)
Exemple - Drapeaux :
// g - global
console.log("aaa".replace(/a/, "b")); // Résultat : "baa"
console.log("aaa".replace(/a/g, "b")); // Résultat : "bbb"
// i - insensible à la casse
console.log(/hello/i.test("HELLO")); // Résultat : true
console.log(/hello/.test("HELLO")); // Résultat : false
// m - multiligne (^ et $ par ligne)
const texte = "ligne1\nligne2\nligne3";
console.log(texte.match(/^ligne/g)); // Résultat : ["ligne"]
console.log(texte.match(/^ligne/gm)); // Résultat : ["ligne", "ligne", "ligne"]
// Combiner les drapeaux
const regex = /hello/gi;
console.log("HELLO hello HeLLo".match(regex));
// Résultat : ["HELLO", "hello", "HeLLo"]
Set et Map
Structure
Méthodes
Description
Set
add(), has(), delete(), clear()
Collection de valeurs uniques
Map
set(), get(), has(), delete()
Paires clé-valeur, clés quelconques
Exemple - Set :
// Créer un Set
const set = new Set();
// Ajouter des valeurs
set.add(1);
set.add(2);
set.add(2); // Ignoré (déjà présent)
set.add(3);
console.log(set.size); // Résultat : 3
console.log(set); // Résultat : Set {1, 2, 3}
// Vérifier présence
console.log(set.has(1)); // Résultat : true
console.log(set.has(5)); // Résultat : false
// Supprimer
set.delete(2);
console.log(set.has(2)); // Résultat : false
// Parcourir
set.forEach(val => console.log(val));
// Résultat : 1, 3
for (let val of set) {
console.log(val);
}
// Cas d'usage : éliminer les doublons
const nombres = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(nombres)];
console.log(unique); // Résultat : [1, 2, 3, 4]
// Vider
set.clear();
console.log(set.size); // Résultat : 0
Exemple - Map :
// Créer une Map
const map = new Map();
// Ajouter des paires clé-valeur
map.set("nom", "Ali");
map.set("age", 25);
map.set(1, "un");
map.set(true, "vrai");
console.log(map.size); // Résultat : 4
// Récupérer une valeur
console.log(map.get("nom")); // Résultat : "Ali"
console.log(map.get("inex")); // Résultat : undefined
// Vérifier présence
console.log(map.has("age")); // Résultat : true
// Supprimer
map.delete(1);
// Parcourir
map.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
for (let [key, value] of map) {
console.log(key, value);
}
// Obtenir clés et valeurs
console.log([...map.keys()]); // Résultat : ["nom", "age", true]
console.log([...map.values()]); // Résultat : ["Ali", 25, "vrai"]
// Initialiser depuis un tableau
const map2 = new Map([
["a", 1],
["b", 2]
]);
console.log(map2.get("a")); // Résultat : 1
Set vs Array :
Set : valeurs uniques, pas d'index, pas de doublons
Map vs Object : Map accepte n'importe quel type comme clé, préserve l'ordre d'insertion
Méthodes de Tableau Statiques
Méthode
Description
Array.from(iterable)
Crée tableau depuis itérable
Array.isArray(val)
Vérifie si c'est un tableau
Array.of(elem1, elem2)
Crée tableau depuis arguments
Exemple - Méthodes statiques :
// Array.from
console.log(Array.from("hello")); // Résultat : ["h", "e", "l", "l", "o"]
console.log(Array.from([1, 2, 3], x => x * 2));
// Résultat : [2, 4, 6]
// Depuis un Set
const set = new Set([1, 2, 2, 3]);
console.log(Array.from(set)); // Résultat : [1, 2, 3]
// Depuis NodeList
const divs = document.querySelectorAll("div");
const divArray = Array.from(divs);
divArray.forEach(div => console.log(div.id));
// Array.isArray
console.log(Array.isArray([1, 2, 3])); // Résultat : true
console.log(Array.isArray("hello")); // Résultat : false
console.log(Array.isArray({ 0: 1, length: 1 })); // Résultat : false
// Array.of
console.log(Array.of(1, 2, 3)); // Résultat : [1, 2, 3]
console.log(Array.of("a", "b")); // Résultat : ["a", "b"]
console.log(Array(3)); // Résultat : [empty × 3]
console.log(Array.of(3)); // Résultat : [3]
Valeurs Falsy et Truthy
Type
Valeurs
Falsy
false, 0, -0, "", null, undefined, NaN, 0n
Truthy
Tout le reste : objets, tableaux, chaînes non vides, nombres non nuls...
Exemple - Falsy et Truthy :
// Valeurs FALSY
const falsy = [false, 0, -0, "", null, undefined, NaN, 0n];
falsy.forEach(val => {
if (val) {
console.log("truthy:", val);
} else {
console.log("falsy:", val);
}
});
// Résultat : tous "falsy"
// Valeurs TRUTHY (attention aux pièges !)
const truthy = [
true,
1,
-1,
"false", // String non vide
"0", // String non vide
[], // Tableau vide
{}, // Objet vide
function(){}, // Fonction
Infinity
];
truthy.forEach(val => {
if (val) {
console.log("truthy:", val);
}
});
// Résultat : tous "truthy"
// Conversion explicite
console.log(Boolean(0)); // Résultat : false
console.log(Boolean("")); // Résultat : false
console.log(Boolean([])); // Résultat : true
console.log(Boolean({})); // Résultat : true
// Double négation
console.log(!!0); // Résultat : false
console.log(!!""); // Résultat : false
console.log(!!1); // Résultat : true
console.log(!![]); // Résultat : true
⚠️ Pièges courants :
[] == false → true (tableau vide est falsy avec ==)
{} == false → false
typeof null → "object" (bug historique)
Conversion de Types
Conversion
Méthode
Exemple
Vers String
String(val) ou val.toString()
String(123) → "123"
Vers Number
Number(val) ou +val
Number("42") → 42
Vers Integer
parseInt(val, base)
parseInt("42px") → 42
Vers Float
parseFloat(val)
parseFloat("3.14px") → 3.14
Vers Boolean
Boolean(val) ou !!val
Boolean(1) → true
Exemple - Conversion de types :
// Vers String
console.log(String(123)); // Résultat : "123"
console.log(String(true)); // Résultat : "true"
console.log(String(null)); // Résultat : "null"
console.log(String(undefined)); // Résultat : "undefined"
console.log((123).toString()); // Résultat : "123"
console.log(123 + ""); // Résultat : "123" (concaténation)
// Vers Number
console.log(Number("42")); // Résultat : 42
console.log(Number("42px")); // Résultat : NaN
console.log(Number("")); // Résultat : 0
console.log(Number(true)); // Résultat : 1
console.log(Number(false)); // Résultat : 0
console.log(+"42"); // Résultat : 42 (unaire +)
// parseInt vs Number
console.log(parseInt("42px")); // Résultat : 42
console.log(parseInt("3.14")); // Résultat : 3
console.log(parseInt("1010", 2)); // Résultat : 10 (binaire)
// parseFloat
console.log(parseFloat("3.14")); // Résultat : 3.14
console.log(parseFloat("3.14px")); // Résultat : 3.14
// Vers Boolean
console.log(Boolean(1)); // Résultat : true
console.log(Boolean(0)); // Résultat : false
console.log(Boolean("")); // Résultat : false
console.log(Boolean("text")); // Résultat : true
console.log(!!1); // Résultat : true
console.log(!!0); // Résultat : false
Timeout et Interval
Méthode
Description
setTimeout(fn, ms)
Exécute après délai (retourne ID)
clearTimeout(id)
Annule setTimeout
setInterval(fn, ms)
Exécute régulièrement (retourne ID)
clearInterval(id)
Annule setInterval
Exemple - setTimeout :
// setTimeout - exécution différée
const timeoutId = setTimeout(() => {
console.log("Exécuté après 2 secondes");
}, 2000);
// Annuler avant exécution
clearTimeout(timeoutId);
// Avec paramètres
setTimeout((nom, age) => {
console.log(`${nom} a ${age} ans`);
}, 1000, "Ali", 25);
// Après 1s : Résultat : "Ali a 25 ans"
// setTimeout immédiat (macro-task)
setTimeout(() => {
console.log("Après le code synchrone");
}, 0);
console.log("Avant");
// Résultat : "Avant" puis "Après le code synchrone"
Exemple - setInterval :
// setInterval - exécution répétée
let compteur = 0;
const intervalId = setInterval(() => {
compteur++;
console.log("Compteur:", compteur);
if (compteur >= 5) {
clearInterval(intervalId); // Arrêter après 5
console.log("Terminé");
}
}, 1000);
// Résultat chaque seconde :
// "Compteur: 1"
// "Compteur: 2"
// "Compteur: 3"
// "Compteur: 4"
// "Compteur: 5"
// "Terminé"
// Horloge
function afficherHeure() {
const maintenant = new Date();
console.log(maintenant.toLocaleTimeString());
}
const horloge = setInterval(afficherHeure, 1000);
// clearInterval(horloge); // Pour arrêter
This en JavaScript
Contexte
Valeur de this
Fonction simple
window (ou undefined en strict mode)
Méthode d'objet
L'objet
Constructeur (new)
La nouvelle instance
Arrow function
Hérite du contexte parent
call/apply/bind
Défini explicitement
Exemple - this :
// Fonction simple
function direThis() {
console.log(this);
}
direThis(); // Résultat : window (ou undefined en strict)
// Méthode d'objet
const personne = {
nom: "Ali",
saluer() {
console.log("Bonjour, je suis " + this.nom);
}
};
personne.saluer(); // Résultat : "Bonjour, je suis Ali"
// Constructeur
function Personne(nom) {
this.nom = nom;
}
const p = new Personne("Sara");
console.log(p.nom); // Résultat : "Sara"
// Arrow function - hérite du parent
const obj = {
nom: "Ali",
methode: () => {
console.log(this.nom); // this = parent (window)
}
};
obj.methode(); // Résultat : undefined
// Callback perd this
const obj2 = {
nom: "Ali",
noms: ["Sara", "Omar"],
afficher() {
this.noms.forEach(function(n) {
console.log(this.nom + " connait " + n);
// this.nom = undefined !
});
}
};
// Solution 1: arrow function
afficher() {
this.noms.forEach(n => {
console.log(this.nom + " connait " + n); // OK
});
}
// Solution 2: bind
afficher() {
this.noms.forEach(function(n) {
console.log(this.nom + " connait " + n);
}.bind(this));
}
Méthodes call, apply, bind
Méthode
Syntaxe
Description
call()
fn.call(thisArg, a, b)
Appelle avec this et arguments individuels
apply()
fn.apply(thisArg, [a, b])
Appelle avec this et tableau d'arguments
bind()
const newFn = fn.bind(thisArg)
Retourne nouvelle fonction avec this lié
Exemple - call, apply, bind :
const personne1 = { nom: "Ali" };
const personne2 = { nom: "Sara" };
function saluer(salutation, punctuation) {
console.log(`${salutation}, je suis ${this.nom}${punctuation}`);
}
// call - arguments individuels
saluer.call(personne1, "Bonjour", "!");
// Résultat : "Bonjour, je suis Ali!"
saluer.call(personne2, "Salut", "?");
// Résultat : "Salut, je suis Sara?"
// apply - arguments en tableau
saluer.apply(personne1, ["Hello", "..."]);
// Résultat : "Hello, je suis Ali..."
// bind - retourne une nouvelle fonction
const saluerAli = saluer.bind(personne1);
saluerAli("Coucou", "!");
// Résultat : "Coucou, je suis Ali!"
// bind avec arguments pré-définis
const direBonjour = saluer.bind(personne2, "Bonjour");
direBonjour("!!!");
// Résultat : "Bonjour, je suis Sara!!!"
// Cas d'usage: emprunter des méthodes
const arrayLike = { 0: "a", 1: "b", 2: "c", length: 3 };
const arr = Array.prototype.slice.call(arrayLike);
console.log(arr); // Résultat : ["a", "b", "c"]
// Math.max avec tableau
const nombres = [5, 1, 9, 3];
console.log(Math.max.apply(null, nombres)); // Résultat : 9
console.log(Math.max(...nombres)); // Résultat : 9 (ES6)
Optional Chaining & Nullish Coalescing
Opérateur
Description
Exemple
?.
Optional chaining
user?.address?.city
??
Nullish coalescing
value ?? "default"
??=
Nullish assignment
a ??= b (si a null/undefined, a = b)
||=
OR assignment
a ||= b (si a falsy, a = b)
&&=
AND assignment
a &&= b (si a truthy, a = b)
Exemple - Optional Chaining :
const user = {
nom: "Ali",
address: {
city: "Paris"
}
};
// Sans optional chaining
let ville;
if (user && user.address && user.address.city) {
ville = user.address.city;
}
// Avec optional chaining
const ville2 = user?.address?.city;
console.log(ville2); // Résultat : "Paris"
// Si propriété inexistante
const pays = user?.address?.country;
console.log(pays); // Résultat : undefined (pas d'erreur!)
// Avec méthodes
const obj = {
methode() { return "Hello"; }
};
console.log(obj.methode?.()); // Résultat : "Hello"
console.log(obj.inexistante?.()); // Résultat : undefined (pas d'erreur)
// Avec tableaux
const arr = [1, 2, 3];
console.log(arr?.[0]); // Résultat : 1
console.log(arr?.[10]); // Résultat : undefined
console.log(obj.nom); // Résultat : "Public"
console.log(obj[_secret]); // Résultat : "Privé"
console.log(Object.keys(obj)); // Résultat : ["nom"] (symbol non listé)
// Symbol.iterator - rendre un objet itérable
const iterableObj = {
data: [1, 2, 3],
[Symbol.iterator]() {
let index = 0;
const data = this.data;
return {
next() {
if (index < data.length) {
return { value: data[index++], done: false };
}
return { done: true };
}
};
}
};
for (let item of iterableObj) {
console.log(item); // Résultat : 1, 2, 3
}
console.log(obj.methode?.()); // Résultat : "Hello"
// Si la méthode n'existe pas
console.log(obj.nonExistant?.()); // Résultat : undefined
// Avec les tableaux
const arr = ["a", "b", "c"];
console.log(arr?.[0]); // Résultat : "a"
console.log(arr?.[100]); // Résultat : undefined
// Supprimer une propriété sûrement
delete user?.address?.country; // Ne plante pas si country n'existe pas
Exemple - Nullish Coalescing (??) :
// ?? retourne la valeur de droite SEULEMENT si gauche est null/undefined
let a = null;
let b = undefined;
let c = 0;
let d = "";
let e = false;
console.log(a ?? "défaut"); // Résultat : "défaut"
console.log(b ?? "défaut"); // Résultat : "défaut"
console.log(c ?? "défaut"); // Résultat : 0 (0 n'est pas null/undefined)
console.log(d ?? "défaut"); // Résultat : "" (chaîne vide n'est pas null/undefined)
console.log(e ?? true); // Résultat : false
// Comparaison avec || (OR)
console.log(c || "défaut"); // Résultat : "défaut" (0 est falsy pour ||)
console.log(d || "défaut"); // Résultat : "défaut" ("" est falsy pour ||)
// Cas d'usage : options par défaut
function config(options) {
const timeout = options.timeout ?? 3000; // 0 est une valeur valide
const retries = options.retries ?? 3; // 0 est une valeur valide
return { timeout, retries };
}
console.log(config({ timeout: 0 }));
// Résultat : { timeout: 0, retries: 3 }
Exemple - Assignations logiques :
let a = null;
let b = "valeur";
// ??= (Nullish assignment)
a ??= "défaut";
console.log(a); // Résultat : "défaut" (a était null)
b ??= "autre";
console.log(b); // Résultat : "valeur" (b n'était pas null/undefined)
// ||= (OR assignment)
let x = 0;
x ||= 10;
console.log(x); // Résultat : 10 (0 est falsy)
let y = 5;
y ||= 10;
console.log(y); // Résultat : 5 (5 est truthy)
// &&= (AND assignment)
let obj = { val: 10 };
obj.val &&= 20;
console.log(obj.val); // Résultat : 20 (val était truthy)
obj.val = 0;
obj.val &&= 30;
console.log(obj.val); // Résultat : 0 (0 est falsy, pas modifié)
Optional Chaining :
obj?.prop : retourne undefined si obj est null/undefined au lieu de lancer une erreur
arr?.[index] : accès sécurisé aux tableaux
fn?.() : appel de fonction sécurisé
Strict Mode
"use strict"
Active le mode strict en début de fichier ou fonction :
• Variables non déclarées → erreur
• Paramètres dupliqués → erreur
• this vaut undefined (pas window)
• delete sur propriétés non supprimables → erreur
Exemple - Strict Mode :
// Sans "use strict"
maVariable = 10; // Crée une variable globale (mauvais)
console.log(maVariable); // Résultat : 10
function dupliqueParams(a, a) {
return a; // Le deuxième écrase le premier
}
console.log(dupliqueParams(1, 2)); // Résultat : 2
// Avec "use strict"
"use strict";
// maVariable = 10; // ❌ ReferenceError: maVariable is not defined
function bonnePratique() {
"use strict";
this; // undefined au lieu de window
}
// function paramsDup(a, a) {} // ❌ SyntaxError
// this global
function testThis() {
"use strict";
console.log(this); // Résultat : undefined
}
testThis();
// Pas de delete sur propriétés natives
// delete Object.prototype; // ❌ TypeError en mode strict
Navigation dans le DOM (Traversing)
Propriété
Description
Retourne
parentNode
Parent direct (peut être n'importe quel noeud)
1 Node
parentElement
Parent direct (uniquement élément HTML)
1 Element
children
Tous les enfants éléments
HTMLCollection
childNodes
Tous les enfants (noeuds texte inclus)
NodeList
firstElementChild
Premier enfant élément
1 Element
lastElementChild
Dernier enfant élément
1 Element
nextElementSibling
Frère suivant (élément)
1 Element
previousElementSibling
Frère précédent (élément)
1 Element
Exemple - Traversing DOM :
// HTML Structure:
//
// Texte avant
// Paragraphe 1
// Texte au milieu
// Paragraphe 2
// Texte après
//
const parent = document.getElementById("parent");
const premierP = parent.querySelector(".premier");
// Remonter
console.log(premierP.parentNode); // Résultat :
console.log(premierP.parentElement); // Résultat :
// Descendre
console.log(parent.children);
// Résultat : HTMLCollection [,
] (elements only)
console.log(parent.childNodes);
// Résultat : NodeList [text,
, text,
, text] (inclut les textes)
console.log(parent.firstElementChild); // Résultat :
console.log(parent.lastElementChild); // Résultat :
// Frères (siblings)
const secondP = premierP.nextElementSibling;
console.log(secondP); // Résultat :
console.log(secondP.previousElementSibling);
// Résultat :
// Parcourir tous les enfants éléments
for (let child of parent.children) {
console.log(child.tagName);
}
// Résultat : "P", "P"
⚠️ Node vs Element :
childNodes inclut les sauts de ligne et espaces (noeuds texte).
children ne retourne que les balises HTML. Préférez les propriétés avec "Element".
Propagation des Événements
Phase
Description
Direction
Capture
L'événement descend du document vers la cible
Window → Target
Target
L'événement atteint l'élément cliqué
Élément précis
Bubbling
L'événement remonte vers les parents
Target → Window
Exemple - Phases de propagation :
// HTML:
const grand = document.getElementById("grand");
const parent = document.getElementById("parent");
const btn = document.getElementById("btn");
// Par défaut : Bubbling (remonte)
grand.addEventListener("click", () => console.log("Grand"));
parent.addEventListener("click", () => console.log("Parent"));
btn.addEventListener("click", () => console.log("Button"));
// Clic sur button => "Button", "Parent", "Grand"
// Avec Capture (descend)
grand.addEventListener("click", () => console.log("Grand Capture"), true);
parent.addEventListener("click", () => console.log("Parent Capture"), true);
// Clic sur button => "Grand Capture", "Parent Capture", "Button", "Parent", "Grand"
// Vérifier la phase
btn.addEventListener("click", (e) => {
console.log("Phase:", e.eventPhase);
// 1 = CAPTURING_PHASE, 2 = AT_TARGET, 3 = BUBBLING_PHASE
});
addEventListener paramètre :
element.addEventListener('click', fn, false)
3ème paramètre : false (défaut) = phase Bubbling, true = phase Capture.
Délégation d'Événements
Concept clé pour éléments dynamiques :
Au lieu d'attacher un écouteur sur chaque élément enfant, on l'attache sur le parent.
ul.addEventListener('click', (e) => { if(e.target.tagName === 'LI') {...} })
Avantages : Fonctionne pour les éléments ajoutés dynamiquement, économise mémoire.
Exemple - Délégation :
// HTML initial
//
// - Item 1
// - Item 2
//
const liste = document.getElementById("liste");
// Délégation : écouteur sur le parent
liste.addEventListener("click", (e) => {
// Vérifier que c'est bien un LI
if (e.target.tagName === "LI") {
console.log("Cliqué sur:", e.target.textContent);
// Style au clic
e.target.classList.toggle("active");
}
});
// Ajouter des éléments dynamiquement
const nouveauItem = document.createElement("li");
nouveauItem.textContent = "Item 3 (dynamique)";
liste.appendChild(nouveauItem);
// Cliquer sur "Item 3" fonctionne aussi !
// Résultat : "Cliqué sur: Item 3 (dynamique)"
// Approche SANS délégation (mauvaise pour dynamique)
document.querySelectorAll("li").forEach(li => {
li.addEventListener("click", () => {
// Ne fonctionne PAS pour les nouveaux éléments
});
});
Formulaires et Validation
Propriété/Méthode
Description
form.elements
Collection des champs du formulaire
input.value
Valeur saisie (string)
input.checked
État d'une checkbox/radio
input.type
Type du champ (text, email, password...)
form.submit()
Soumet le formulaire via JS
form.reset()
Réinitialise les champs
e.preventDefault()
Bloque l'envoi classique du formulaire
Exemple - Gestion de formulaire :
//
const form = document.getElementById("monForm");
form.addEventListener("submit", (e) => {
e.preventDefault(); // Empêche le rechargement
// Accès via form.elements
const nom = form.elements.nom.value;
const email = form.elements.email.value;
const accept = form.elements.accept.checked;
console.log("Nom:", nom);
console.log("Email:", email);
console.log("Accepté:", accept);
// Validation manuelle
if (!nom) {
alert("Le nom est requis");
return;
}
// Validation email simple
if (email && !email.includes("@")) {
alert("Email invalide");
return;
}
// Envoi des données (exemple avec FormData)
const formData = new FormData(form);
console.log("FormData:", Object.fromEntries(formData));
// Résultat : { nom: "Ali", email: "ali@email.com", accept: "on" }
// Réinitialiser après envoi
form.reset();
});
Validation HTML5 vs JS
Validation HTML5
Validation JS
required, pattern="regex"
Logique conditionnelle personnalisée
type="email", min="5"
input.checkValidity()
Pseudo-classes CSS (:valid, :invalid)
Messages d'erreur personnalisés dynamiques
Exemple - Validation combinée :
//
const password = document.getElementById("password");
// Validation HTML5 avec checkValidity
password.addEventListener("input", () => {
if (password.validity.tooShort) {
password.setCustomValidity(
`Min 8 caractères (${password.value.length}/8)`
);
} else if (!/[A-Z]/.test(password.value)) {
password.setCustomValidity("Une majuscule requise");
} else {
password.setCustomValidity(""); // Tout est OK
}
password.reportValidity(); // Affiche le message
});
// Vérifier tout le formulaire
const form = document.querySelector("form");
form.addEventListener("submit", (e) => {
if (!form.checkValidity()) {
e.preventDefault();
// Afficher les erreurs
}
});
// Pseudo-classes CSS (automatique)
// input:valid { border-color: green; }
// input:invalid { border-color: red; }
AJAX (Asynchronous JavaScript And XML)
Technologie
Caractéristique
XMLHttpRequest (XHR)
Ancien, basé sur callbacks, verbeux
fetch()
Moderne, basé sur Promises, plus simple
Axios (Librairie)
Wrapper HTTP populaire, gère erreurs JSON automatiquement
Exemple XMLHttpRequest (Classique)
Étape
Code
1. Création
const xhr = new XMLHttpRequest();
2. Configuration
xhr.open('GET', 'url', true);
3. Callback
xhr.onload = function() { ... }
4. Envoi
xhr.send();
Exemple - XHR complet :
const xhr = new XMLHttpRequest();
// Configuration
xhr.open("GET", "https://jsonplaceholder.typicode.com/users/1", true);
// Callback de succès
xhr.onload = function() {
if (this.status === 200 && this.readyState === 4) {
const data = JSON.parse(this.responseText);
console.log("Utilisateur:", data.name);
}
};
// Callback d'erreur
xhr.onerror = function() {
console.error("Erreur réseau");
};
// Suivi du progrès (upload/download)
xhr.onprogress = function(e) {
if (e.lengthComputable) {
console.log(`${e.loaded}/${e.total} bytes`);
}
};
// Envoyer la requête
xhr.send();
⚠️ readyState (XHR) :
0: Non initialisé | 1: Connexion ouverte | 2: Reçue | 3: En cours | 4: Terminée
On vérifie généralement if (xhr.readyState === 4 && xhr.status === 200)
Fetch API (Moderne)
Exemple GET
Exemple POST
fetch('url')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
fetch('url', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
})
Exemple - Fetch avancé :
// Gestion complète des erreurs
async function apiRequest(url, options = {}) {
try {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
...options.headers
},
...options
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
return { success: true, data };
} catch (error) {
console.error('API Error:', error);
return { success: false, error: error.message };
}
}
// Utilisation
const result = await apiRequest(
'https://jsonplaceholder.typicode.com/posts',
{
method: 'POST',
body: JSON.stringify({ title: 'Test', body: 'Contenu', userId: 1 })
}
);
if (result.success) {
console.log("Créé:", result.data);
}
// Timeout avec AbortController
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(timeoutId);
const data = await response.json();
} catch (e) {
if (e.name === 'AbortError') {
console.log("Requête annulée (timeout)");
}
}
Fetch n'échoue pas sur erreur HTTP (404, 500)
Il faut vérifier manuellement : if (!response.ok) throw new Error(...)
Fetch n'échoue dans .catch que sur erreurs réseau.
Async/Await avec Fetch
Syntaxe recommandée
async function getData() {
try {
const res = await fetch('url');
if (!res.ok) throw new Error('Erreur HTTP');
const data = await res.json();
console.log(data);
} catch (e) { console.error(e); }
}
Exemple - Pattern complet async/await :
class APIClient {
constructor(baseUrl) {
this.baseUrl = baseUrl;
}
async get(endpoint) {
const response = await fetch(`${this.baseUrl}${endpoint}`);
return this._handleResponse(response);
}
async post(endpoint, data) {
const response = await fetch(`${this.baseUrl}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
return this._handleResponse(response);
}
async _handleResponse(response) {
if (!response.ok) {
const error = await response.text();
throw new Error(`API Error ${response.status}: ${error}`);
}
return response.json();
}
}
// Utilisation
const api = new APIClient('https://jsonplaceholder.typicode.com');
async function loadData() {
try {
const users = await api.get('/users');
console.log(`${users.length} utilisateurs`);
const newUser = await api.post('/users', {
name: 'Ali',
email: 'ali@test.com'
});
console.log("Créé:", newUser);
} catch (error) {
console.error("Erreur:", error.message);
}
}
loadData();
JSON (JavaScript Object Notation)
Règle JSON
Exemple
Clés entre guillemets doubles
{"nom": "Ali"} (pas de {nom: "Ali"})
Pas de virgule finale
{"a":1,} ❌ Invalide
Types autorisés
String, Number, Boolean, null, Array, Object
Types interdits
Function, Date, undefined
Exemple - Gestion JSON :
// Objet JS vers JSON
const obj = {
nom: "Ali",
age: 25,
hobbies: ["sport", "musique"],
actif: true
};
const json = JSON.stringify(obj);
console.log(json);
// Résultat : '{"nom":"Ali","age":25,"hobbies":["sport","musique"],"actif":true}'
// JSON vers Objet JS
const parsed = JSON.parse(json);
console.log(parsed.nom); // Résultat : "Ali"
// Sauvegarder dans localStorage
localStorage.setItem("user", JSON.stringify(obj));
// Récupérer depuis localStorage
const saved = JSON.parse(localStorage.getItem("user"));
// Deep clone avec JSON
const clone = JSON.parse(JSON.stringify(obj));
// Gestion des erreurs
try {
const data = JSON.parse('{"invalide}');
} catch (e) {
console.error("JSON invalide:", e.message);
}
// Reviver function (transformation lors du parse)
const data = JSON.parse('{"date":"2024-01-01"}', (key, value) => {
if (key === "date") return new Date(value);
return value;
});
console.log(data.date.getFullYear()); // Résultat : 2024
jQuery (Rappel rapide)
Note : jQuery simplifie la sélection DOM et les effets, mais est moins utilisé dans le JS moderne (ES6+). Utile pour maintenance de vieux projets.
Sélecteur
jQuery
JS Équivalent
Par ID
$('#monId')
document.getElementById('monId')
Par Classe
$('.maClasse')
document.querySelectorAll('.maClasse')
Par Tag
$('div')
document.getElementsByTagName('div')
Exemple - jQuery vs Vanilla JS :
// JQUERY
// Sélection
$('#id').css('color', 'red');
$('.class').hide();
// Événement
$('#btn').on('click', function() {
$(this).toggleClass('active');
});
// AJAX
$.ajax({
url: '/api/data',
method: 'GET',
success: function(data) {
console.log(data);
}
});
// VANILLA JS (ES6+)
// Sélection
document.getElementById('id').style.color = 'red';
document.querySelectorAll('.class').forEach(el => el.style.display = 'none');
// Événement
document.getElementById('btn').addEventListener('click', function() {
this.classList.toggle('active');
});
// AJAX
fetch('/api/data')
.then(res => res.json())
.then(data => console.log(data));
jQuery Méthodes Courantes
Catégorie
Méthode
Description
Contenu
.html() / .text()
Getter/Setter innerHTML / textContent
Valeur
.val()
Getter/Setter value (inputs)
Attributs
.attr('src')
Getter/Setter attributs
CSS
.css('color', 'red')
Modifier le style
Classes
.addClass() / .removeClass()
Gérer les classes
Events
.on('click', fn)
Attachement d'événements
AJAX
$.ajax({ url: '...', success: fn })
Requêtes HTTP
Effets
.hide() / .show() / .fadeIn()
Animations simples
Chaînage jQuery
Syntaxe
$('.box')
.css('background', 'blue')
.fadeIn(500)
.text('Terminé');
Exemple - Chaînage jQuery :
// Chaînage
$('.card')
.addClass('active')
.css({ 'background': 'blue', 'color': 'white' })
.fadeIn(300)
.find('.title')
.text('Nouveau titre')
.end() // Retourne à .card
.on('click', function() {
$(this).toggleClass('expanded');
});
// Équivalent Vanilla JS (plus verbeux mais standard)
const cards = document.querySelectorAll('.card');
cards.forEach(card => {
card.classList.add('active');
Object.assign(card.style, { background: 'blue', color: 'white' });
card.style.display = 'block';
const title = card.querySelector('.title');
if (title) title.textContent = 'Nouveau titre';
card.addEventListener('click', () => {
card.classList.toggle('expanded');
});
});
⚠️ Objet jQuery vs Element DOM :
$('#id') retourne un objet jQuery.
document.getElementById('id') retourne un Element DOM.
On ne peut pas utiliser $('#id').addEventListener ni elementDom.text().
Conversion jQuery ↔ DOM :
// jQuery vers DOM
const $element = $('#monId');
const domElement = $element[0]; // ou $element.get(0)
// DOM vers jQuery
const domEl = document.getElementById('monId');
const $el = $(domEl);
// Exemple pratique
$('#id')[0].addEventListener('click', handler); // Mixte
// Récupérer la valeur d'un input
console.log($('input').val()); // jQuery
console.log($('input')[0].value); // DOM
// Parcourir une collection jQuery
$('li').each(function(index) {
console.log(index, $(this).text());
// this = élément DOM brut
// $(this) = objet jQuery
});
🗄️ SQL & NoSQL
Définition : SQL (Structured Query Language) pour bases relationnelles avec schéma fixe vs NoSQL (Not Only SQL) pour bases flexibles sans schéma rigide.
Commandes SQL Essentielles - DQL (Data Query Language)
Commande
Action
Exemple / Options
SELECT
Lire données d'une ou plusieurs tables
SELECT nom, age FROM users WHERE age > 20;
SELECT * FROM users; -- Toutes les colonnes
SELECT DISTINCT ville FROM users; -- Valeurs uniques
WHERE
Filtrer les lignes selon condition
WHERE age > 18 AND ville = 'Paris'
WHERE nom LIKE 'A%' -- Commence par A
WHERE id IN (1, 2, 3) -- Dans la liste
ORDER BY
Trier les résultats
ORDER BY age ASC; -- Croissant (défaut)
ORDER BY nom DESC; -- Décroissant
ORDER BY age DESC, nom ASC; -- Multi-colonnes
LIMIT / OFFSET
Limiter le nombre de résultats
LIMIT 10; -- 10 premiers
LIMIT 10 OFFSET 20; -- 10 résultats à partir du 21ème
LIMIT 20, 10; -- MySQL (offset, limit)
GROUP BY
Regrouper lignes selon colonne(s)
SELECT ville, COUNT(*) FROM users GROUP BY ville;
HAVING
Filtrer les groupes après regroupement
SELECT ville, COUNT(*) FROM users
GROUP BY ville HAVING COUNT(*) > 5;
JOIN
Combiner données de plusieurs tables
SELECT u.nom, c.nom
FROM users u
INNER JOIN commandes c ON u.id = c.user_id;
ALIAS (AS)
Renommer colonnes ou tables
SELECT nom AS prenom FROM users;
SELECT u.nom, c.montant FROM users AS u;
Exemple - Table users utilisée :
-- Table: users
-- +----+-------+-----+--------+
-- | id | nom | age | ville |
-- +----+-------+-----+--------+
-- | 1 | Ali | 25 | Paris |
-- | 2 | Sara | 30 | Lyon |
-- | 3 | Omar | 25 | Paris |
-- | 4 | Lina | 22 | Marseille |
-- +----+-------+-----+--------+
Exemple - SELECT et WHERE :
-- Sélectionner nom et age des users de Paris
SELECT nom, age FROM users WHERE ville = 'Paris';
-- Résultat :
-- +------+-----+
-- | nom | age |
-- +------+-----+
-- | Ali | 25 |
-- | Omar | 25 |
-- +------+-----+
-- Valeurs uniques de villes
SELECT DISTINCT ville FROM users;
-- Résultat :
-- +-----------+
-- | ville |
-- +-----------+
-- | Paris |
-- | Lyon |
-- | Marseille |
-- +-----------+
-- Filtrage avec LIKE
SELECT * FROM users WHERE nom LIKE 'A%';
-- Résultat : La ligne de 'Ali' (commence par A)
-- Opérateurs logiques
SELECT * FROM users WHERE age >= 25 AND ville = 'Paris';
-- Résultat : Ali et Omar
Exemple - ORDER BY et LIMIT :
-- Trier par age décroissant, puis nom croissant
SELECT * FROM users ORDER BY age DESC, nom ASC;
-- Résultat :
-- +----+-------+-----+-----------+
-- | id | nom | age | ville |
-- +----+-------+-----+-----------+
-- | 2 | Sara | 30 | Lyon |
-- | 1 | Ali | 25 | Paris |
-- | 3 | Omar | 25 | Paris |
-- | 4 | Lina | 22 | Marseille |
-- +----+-------+-----+-----------+
-- Pagination : 2 résultats par page, page 2
SELECT * FROM users LIMIT 2 OFFSET 2;
-- Résultat (saute les 2 premiers) :
-- +----+------+-----+-----------+
-- | id | nom | age | ville |
-- +----+------+-----+-----------+
-- | 3 | Omar | 25 | Paris |
-- | 4 | Lina | 22 | Marseille |
-- +----+------+-----+-----------+
Exemple - GROUP BY et HAVING :
-- Compter les utilisateurs par ville
SELECT ville, COUNT(*) as nb_users
FROM users
GROUP BY ville;
-- Résultat :
-- +-----------+----------+
-- | ville | nb_users |
-- +-----------+----------+
-- | Paris | 2 |
-- | Lyon | 1 |
-- | Marseille | 1 |
-- +-----------+----------+
-- Uniquement les villes avec plus d'1 user
SELECT ville, COUNT(*) as nb_users
FROM users
GROUP BY ville
HAVING COUNT(*) > 1;
-- Résultat :
-- +-------+----------+
-- | ville | nb_users |
-- +-------+----------+
-- | Paris | 2 |
-- +-------+----------+
-- Age moyen par ville
SELECT ville, AVG(age) as moyenne
FROM users
GROUP BY ville;
-- Résultat :
-- Paris a une moyenne de 25.0000
Commandes SQL - DML (Data Manipulation Language)
Commande
Action
Exemple / Syntaxe
INSERT INTO
Ajouter de nouvelles lignes
INSERT INTO users (nom, age) VALUES ('Marie', 25);
INSERT INTO users VALUES (1, 'Marie', 25); -- Toutes colonnes
INSERT INTO users (nom) VALUES ('A'), ('B'), ('C'); -- Multi-lignes
UPDATE
Modifier des lignes existantes
UPDATE users SET age = 26 WHERE id = 1;
UPDATE users SET age = age + 1; -- Incrémente tout le monde
UPDATE users SET nom = 'Jane', age = 30 WHERE id = 1;
DELETE
Supprimer des lignes
DELETE FROM users WHERE id = 1;
DELETE FROM users; -- ⚠️ Supprime TOUT (sans WHERE)
DELETE FROM users WHERE age < 18;
TRUNCATE
Vider complètement une table (rapide)
TRUNCATE TABLE users; -- Supprime tout, reset auto-increment
-- Plus rapide que DELETE sans WHERE, pas de rollback
Exemple - INSERT :
-- Insérer un utilisateur
INSERT INTO users (nom, age, ville) VALUES ('Marie', 28, 'Bordeaux');
-- Vérification
SELECT * FROM users WHERE nom = 'Marie';
-- Résultat :
-- +----+-------+-----+----------+
-- | id | nom | age | ville |
-- +----+-------+-----+----------+
-- | 5 | Marie | 28 | Bordeaux |
-- +----+-------+-----+----------+
-- Insertion multiple
INSERT INTO users (nom, age) VALUES
('Paul', 35),
('Emma', 29);
-- Résultat : 2 nouvelles lignes ajoutées
Exemple - UPDATE :
-- Avant
SELECT nom, age FROM users WHERE id = 1;
-- Ali, 25
-- Mise à jour
UPDATE users SET age = 26 WHERE id = 1;
-- Résultat : Query OK, 1 row affected
-- Après
SELECT nom, age FROM users WHERE id = 1;
-- Ali, 26
-- Mise à jour conditionnelle
UPDATE users SET ville = 'Paris' WHERE age > 30;
-- Tous les users de plus de 30 ans déménagent à Paris
-- ⚠️ SANS WHERE : modifie TOUTES les lignes
UPDATE users SET ville = 'Paris';
-- Résultat : Query OK, 5 rows affected (tous modifiés !)
Exemple - DELETE vs TRUNCATE :
-- DELETE avec filtre
DELETE FROM users WHERE age < 25;
-- Résultat : Supprime Lina (22 ans)
-- DELETE sans filtre (dangereux)
DELETE FROM users;
-- Résultat : Toutes les lignes supprimées
-- Mais : L'auto-increment garde son compteur
-- Prochain INSERT aura id = 6 (pas 1)
-- TRUNCATE (réinitialise tout)
TRUNCATE TABLE users;
-- Résultat : Table vide + Auto-increment remis à 1
-- Plus rapide car ne loggue pas chaque ligne
-- ⚠️ Ne peut pas être annulé (ROLLBACK impossible dans certains SGBD)
Commandes SQL - DDL (Data Definition Language)
Commande
Action
Exemple / Syntaxe
CREATE TABLE
Créer une nouvelle table
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
nom VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE,
age INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
ALTER TABLE
Modifier structure d'une table
ALTER TABLE users ADD COLUMN telephone VARCHAR(20);
ALTER TABLE users DROP COLUMN telephone;
ALTER TABLE users MODIFY COLUMN age SMALLINT;
ALTER TABLE users RENAME TO clients;
DROP TABLE
Supprimer une table définitivement
DROP TABLE users; -- ⚠️ Supprime structure + données
DROP TABLE IF EXISTS users; -- Sans erreur si inexistant
CREATE INDEX
Créer un index pour accélérer recherches
CREATE INDEX idx_nom ON users(nom);
CREATE UNIQUE INDEX idx_email ON users(email);
Exemple - CREATE TABLE :
-- Création d'une table complète
CREATE TABLE produits (
id INT PRIMARY KEY AUTO_INCREMENT,
nom VARCHAR(100) NOT NULL,
prix DECIMAL(10, 2) NOT NULL,
stock INT DEFAULT 0,
categorie_id INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_nom (nom),
FOREIGN KEY (categorie_id) REFERENCES categories(id)
);
-- Résultat : Table 'produits' créée
DESCRIBE produits;
-- +--------------+---------------+------+-----+-------------------+
-- | Field | Type | Null | Key | Default |
-- +--------------+---------------+------+-----+-------------------+
-- | id | int | NO | PRI | NULL |
-- | nom | varchar(100) | NO | UNI | NULL |
-- | prix | decimal(10,2) | NO | | NULL |
-- | stock | int | YES | | 0 |
-- | categorie_id | int | YES | MUL | NULL |
-- | created_at | timestamp | YES | | CURRENT_TIMESTAMP |
-- +--------------+---------------+------+-----+-------------------+
Exemple - ALTER TABLE :
-- Ajouter une colonne
ALTER TABLE produits ADD COLUMN description TEXT;
-- Résultat : Nouvelle colonne 'description' ajoutée
-- Modifier une colonne
ALTER TABLE produits MODIFY COLUMN prix DECIMAL(12, 2);
-- Résultat : Précision du prix augmentée
-- Renommer une colonne
ALTER TABLE produits CHANGE COLUMN nom nom_produit VARCHAR(150);
-- Résultat : Colonne 'nom' renommée en 'nom_produit'
-- Supprimer une colonne
ALTER TABLE produits DROP COLUMN description;
-- Résultat : Colonne supprimée (données perdues)
-- Supprimer la table
DROP TABLE IF EXISTS produits;
-- Résultat : Table supprimée définitivement
Contraintes SQL (Constraints)
Contrainte
Description
Exemple
PRIMARY KEY
Identifiant unique de la ligne (non null + unique)
id INT PRIMARY KEY ou PRIMARY KEY (id, code)
FOREIGN KEY
Lien vers clé primaire d'une autre table
user_id INT,
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE ON UPDATE CASCADE
NOT NULL
Colonne obligatoire (pas de valeur NULL)
nom VARCHAR(50) NOT NULL
UNIQUE
Valeur unique dans la table
email VARCHAR(100) UNIQUE
DEFAULT
Valeur par défaut si non spécifiée
status VARCHAR(20) DEFAULT 'actif'
CHECK
Vérifie une condition sur la valeur
age INT CHECK (age >= 0)
AUTO_INCREMENT
Incrémentation automatique (MySQL)
id INT AUTO_INCREMENT PRIMARY KEY
Exemple - Contraintes en action :
-- Table avec contraintes
CREATE TABLE commandes (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
montant DECIMAL(10,2) NOT NULL CHECK (montant > 0),
status VARCHAR(20) DEFAULT 'en_cours',
date_commande DATETIME DEFAULT CURRENT_TIMESTAMP,
-- Clé étrangère
CONSTRAINT fk_user
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE -- Si user supprimé, supprimer commandes
ON UPDATE CASCADE
);
-- Test violation NOT NULL
INSERT INTO commandes (user_id, montant) VALUES (NULL, 100);
-- Résultat : ERROR 1048: Column 'user_id' cannot be null
-- Test violation CHECK
INSERT INTO commandes (user_id, montant) VALUES (1, -50);
-- Résultat : ERROR 3819: Check constraint violated
-- Test DEFAULT
INSERT INTO commandes (user_id, montant) VALUES (1, 100);
SELECT * FROM commandes WHERE id = LAST_INSERT_ID();
-- Résultat : status = 'en_cours' (défaut appliqué)
Fonctions d'Agrégation (Aggregate Functions)
Fonction
Action
Exemple
COUNT(*)
Compte le nombre de lignes
SELECT COUNT(*) FROM users; → Nombre total
COUNT(col)
Compte les valeurs non NULL
SELECT COUNT(email) FROM users;
SUM(col)
Somme des valeurs
SELECT SUM(montant) FROM commandes;
AVG(col)
Moyenne des valeurs
SELECT AVG(age) FROM users;
MIN(col)
Valeur minimale
SELECT MIN(prix) FROM produits;
MAX(col)
Valeur maximale
SELECT MAX(salaire) FROM employes;
GROUP_CONCAT()
Concatène valeurs d'un groupe
SELECT GROUP_CONCAT(nom) FROM users; → "A,B,C"
Exemple - Agrégations :
-- Table commandes:
-- +----+---------+--------+
-- | id | user_id | montant|
-- +----+---------+--------+
-- | 1 | 1 | 150 |
-- | 2 | 1 | 80 |
-- | 3 | 2 | 200 |
-- | 4 | 3 | 50 |
-- +----+---------+--------+
-- COUNT : Nombre total de commandes
SELECT COUNT(*) as total FROM commandes;
-- Résultat : 4
-- SUM : Chiffre d'affaires total
SELECT SUM(montant) as ca_total FROM commandes;
-- Résultat : 480
-- AVG : Montant moyen
SELECT AVG(montant) as moyenne FROM commandes;
-- Résultat : 120.0000
-- MIN / MAX
SELECT MIN(montant) as min, MAX(montant) as max FROM commandes;
-- Résultat : min = 50, max = 200
-- Agrégation par groupe
SELECT user_id,
COUNT(*) as nb_commandes,
SUM(montant) as total
FROM commandes
GROUP BY user_id;
-- Résultat :
-- +---------+--------------+-------+
-- | user_id | nb_commandes | total |
-- +---------+--------------+-------+
-- | 1 | 2 | 230 |
-- | 2 | 1 | 200 |
-- | 3 | 1 | 50 |
-- +---------+--------------+-------+
Jointures (JOIN) - Explications Détaillées
Type
Description
Exemple / Schéma
INNER JOIN
Intersection : uniquement les correspondances dans LES DEUX tables
SELECT u.nom, c.montant
FROM users u
INNER JOIN commandes c ON u.id = c.user_id;
-- Résultat : uniquement users AVEC commandes
LEFT JOIN (ou LEFT OUTER JOIN)
TOUTES les lignes table gauche + correspondances droite (NULL si pas de correspondance)
SELECT u.nom, c.montant
FROM users u
LEFT JOIN commandes c ON u.id = c.user_id;
-- Résultat : tous les users, même sans commande (montant = NULL)
RIGHT JOIN
TOUTES les lignes table droite + correspondances gauche
-- Inverse de LEFT JOIN
-- Toutes les commandes même sans user associé
FULL OUTER JOIN
Union : toutes les lignes des deux tables (correspondances + non-correspondances)
-- MySQL : pas natif, simulé avec UNION
-- Tous les users ET toutes les commandes
CROSS JOIN
Produit cartésien : toutes les combinaisons possibles
SELECT * FROM users
CROSS JOIN produits;
-- 100 users × 50 produits = 5000 lignes
SELF JOIN
Jointure d'une table avec elle-même
-- Employés et leurs managers
SELECT e.nom, m.nom AS manager
FROM employes e
JOIN employes m ON e.manager_id = m.id;
Exemple - Jeux de données :
-- Table users:
-- +----+------+
-- | id | nom |
-- +----+------+
-- | 1 | Ali |
-- | 2 | Sara |
-- | 3 | Omar |
-- +----+------+
-- Table commandes:
-- +----+---------+---------+
-- | id | user_id | montant |
-- +----+---------+---------+
-- | 1 | 1 | 150 |
-- | 2 | 1 | 80 |
-- | 3 | 2 | 200 |
-- +----+---------+---------+
-- Note : Omar (id=3) n'a aucune commande
Exemple - INNER JOIN :
-- INNER JOIN : Intersection uniquement
SELECT u.nom, c.montant
FROM users u
INNER JOIN commandes c ON u.id = c.user_id;
-- Résultat :
-- +------+---------+
-- | nom | montant |
-- +------+---------+
-- | Ali | 150 |
-- | Ali | 80 |
-- | Sara | 200 |
-- +------+---------+
-- Omar n'apparaît pas (pas de commande)
Exemple - LEFT JOIN :
-- LEFT JOIN : Tous les users, même sans commandes
SELECT u.nom, c.montant
FROM users u
LEFT JOIN commandes c ON u.id = c.user_id;
-- Résultat :
-- +------+---------+
-- | nom | montant |
-- +------+---------+
-- | Ali | 150 |
-- | Ali | 80 |
-- | Sara | 200 |
-- | Omar | NULL | <-- Inclus avec NULL
-- +------+---------+
-- Trouver les users SANS commandes
SELECT u.nom
FROM users u
LEFT JOIN commandes c ON u.id = c.user_id
WHERE c.id IS NULL;
-- Résultat : Omar
Exemple - SELF JOIN :
-- Table employes:
-- +----+--------+------------+
-- | id | nom | manager_id |
-- +----+--------+------------+
-- | 1 | Ali | NULL | (Directeur)
-- | 2 | Sara | 1 |
-- | 3 | Omar | 1 |
-- | 4 | Lina | 2 |
-- +----+--------+------------+
-- Qui est le manager de qui ?
SELECT e.nom AS employe, m.nom AS manager
FROM employes e
LEFT JOIN employes m ON e.manager_id = m.id;
-- Résultat :
-- +---------+---------+
-- | employe | manager |
-- +---------+---------+
-- | Ali | NULL | (Pas de manager)
-- | Sara | Ali |
-- | Omar | Ali |
-- | Lina | Sara |
-- +---------+---------+
Opérateurs SQL
Catégorie
Opérateurs
Description / Exemple
Comparaison
=, !=, <>, <, >, <=, >=
WHERE age >= 18 AND age <= 65
Logiques
AND, OR, NOT
WHERE (age > 18 OR pays = 'FR') AND NOT bloque
Intervalle
BETWEEN
WHERE age BETWEEN 18 AND 25 (inclus)
Liste
IN, NOT IN
WHERE pays IN ('FR', 'BE', 'CH')
Pattern
LIKE, NOT LIKE
WHERE nom LIKE 'A%' (% = plusieurs _, _ = 1 caractère)
NULL
IS NULL, IS NOT NULL
WHERE email IS NOT NULL (pas = NULL)
Existence
EXISTS, NOT EXISTS
WHERE EXISTS (SELECT 1 FROM commandes WHERE user_id = u.id)
Exemple - Opérateurs :
-- BETWEEN (inclusif)
SELECT * FROM users WHERE age BETWEEN 25 AND 30;
-- Résultat : Ali (25), Sara (30), Omar (25)
-- IN (liste de valeurs)
SELECT * FROM users WHERE ville IN ('Paris', 'Lyon');
-- Résultat : Ali, Sara, Omar
-- LIKE (recherche de motifs)
SELECT * FROM users WHERE nom LIKE '%a%';
-- Résultat : Ali, Sara, Lina (contiennent 'a')
SELECT * FROM users WHERE nom LIKE '_li';
-- Résultat : Ali (_ = 1 caractère, puis 'li')
-- NULL (attention !)
SELECT * FROM users WHERE email = NULL; -- ❌ Ne fonctionne pas
SELECT * FROM users WHERE email IS NULL; -- ✅ Correct
-- EXISTS (sous-requête)
SELECT nom FROM users u
WHERE EXISTS (
SELECT 1 FROM commandes c WHERE c.user_id = u.id
);
-- Résultat : Users ayant au moins une commande (Ali, Sara)
WHERE vs HAVING :
WHERE : filtre les LIGNES avant regroupement (pas de fonctions d'agrégation)
HAVING : filtre les GROUPES après regroupement (peut utiliser COUNT, SUM, etc.)
Ordre d'exécution SQL : FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
Exemple - WHERE vs HAVING :
-- SCÉNARIO : Users de Paris ayant passé plus de 1 commande
-- Table users: id, nom, ville
-- Table commandes: id, user_id, montant
-- ❌ ERREUR : WHERE ne peut pas utiliser COUNT
SELECT u.nom, COUNT(c.id) as nb
FROM users u
JOIN commandes c ON u.id = c.user_id
WHERE u.ville = 'Paris' AND COUNT(c.id) > 1; -- ERREUR !
-- ✅ CORRECT : WHERE pour filtre ligne, HAVING pour filtre groupe
SELECT u.nom, COUNT(c.id) as nb
FROM users u
JOIN commandes c ON u.id = c.user_id
WHERE u.ville = 'Paris' -- 1. Filtre les lignes (Paris seulement)
GROUP BY u.id, u.nom -- 2. Groupe par user
HAVING COUNT(c.id) > 1; -- 3. Filtre les groupes (plus d'1 commande)
-- Résultat : Ali (2 commandes à Paris)
SQL vs NoSQL - Comparaison Détaillée
Critère
SQL (Relationnel)
NoSQL (Non-relationnel)
Structure
Tables avec lignes et colonnes fixes
Documents, clés-valeurs, graphes, colonnes (flexible)
Schéma
Rigide (défini à l'avance, ALTER pour modifier)
Dynamique (sans schéma prédéfini, évolutif)
Langage
SQL standardisé
API spécifique ou langage de requête propre
Scalabilité
Verticale (serveur plus puissant)
Horizontale (ajout de serveurs, sharding)
Jointures
Natives et optimisées (JOIN)
Non supportées ou dénormalisées (embarquées)
Transactions
ACID complètes (Atomicité, Cohérence, Isolation, Durabilité)
BASE (Basically Available, Soft state, Eventually consistent)
Cas d'usage
Données structurées, transactions complexes, reporting
Big Data, temps réel, contenu varié, haute disponibilité
Exemples
MySQL, PostgreSQL, Oracle, SQL Server
MongoDB, Redis, Cassandra, Neo4j, Couchbase
Types NoSQL - Détail par Catégorie
Type
Structure
Exemple
Usage / Cas d'usage
Document
Documents JSON/BSON (clé-valeur hiérarchique)
MongoDB, CouchDB
Contenu web, catalogues produits, CMS, données semi-structurées
Key-Value
Clé unique → Valeur (string, blob, etc.)
Redis, DynamoDB, Riak
Cache, sessions utilisateur, paniers e-commerce, temps réel
Column Family
Colonnes groupées en familles (sparse)
Cassandra, HBase
Big Data, logs, time-series, analytics massive
Graph
Nœuds + Relations + Propriétés
Neo4j, Amazon Neptune
Réseaux sociaux, recommandations, fraude, knowledge graphs
Exemple - SQL vs NoSQL (Structure) :
-- SQL (Table 'users')
-- +----+------+-----+--------+
-- | id | nom | age | ville |
-- +----+------+-----+--------+
-- | 1 | Ali | 25 | Paris |
-- +----+------+-----+--------+
-- NoSQL - Document (MongoDB)
{
"_id": ObjectId("507f1f77bcf86cd799439011"),
"nom": "Ali",
"age": 25,
"adresse": {
"ville": "Paris",
"cp": "75001"
},
"hobbies": ["sport", "musique"], // Données imbriquées
"actif": true
}
-- NoSQL - Key-Value (Redis)
SET user:1 '{"nom":"Ali","age":25}'
GET user:1
-- Résultat : '{"nom":"Ali","age":25}'
-- NoSQL - Graph (Neo4j - Cypher)
CREATE (u:User {nom: 'Ali'})-[:LIVES_IN]->(c:City {nom: 'Paris'});
Exemples de Requêtes NoSQL (MongoDB)
Opération
SQL
MongoDB (NoSQL)
Lire tous
SELECT * FROM users;
db.users.find();
Lire avec filtre
SELECT * FROM users WHERE age > 20;
db.users.find({ age: { $gt: 20 } });
Lire colonnes spécifiques
SELECT nom, age FROM users;
db.users.find({}, { nom: 1, age: 1, _id: 0 });
Insérer
INSERT INTO users (nom, age) VALUES ('Marie', 25);
db.users.insertOne({ nom: 'Marie', age: 25 });
Mettre à jour
UPDATE users SET age = 26 WHERE id = 1;
db.users.updateOne({ _id: 1 }, { $set: { age: 26 } });
Supprimer
DELETE FROM users WHERE id = 1;
db.users.deleteOne({ _id: 1 });
Compter
SELECT COUNT(*) FROM users;
db.users.countDocuments();
Exemple - Requêtes MongoDB avec résultats :
// Collection users (équivalent table SQL)
// { "_id": 1, "nom": "Ali", "age": 25, "ville": "Paris" }
// { "_id": 2, "nom": "Sara", "age": 30, "ville": "Lyon" }
// Trouver tous les users
db.users.find();
// Résultat : Tous les documents
// Filtrer (age > 25)
db.users.find({ age: { $gt: 25 } });
// Résultat : { "_id": 2, "nom": "Sara", "age": 30, ... }
// Opérateurs MongoDB :
// $gt (>) , $gte (>=), $lt (<), $lte (<=), $ne (!=)
// $in (IN), $nin (NOT IN), $exists (existe)
// Combinaison de conditions
db.users.find({
age: { $gte: 20, $lte: 30 },
ville: { $in: ["Paris", "Lyon"] }
});
// Résultat : Ali et Sara
// Projection (colonnes spécifiques)
db.users.find({}, { nom: 1, age: 1, _id: 0 });
// Résultat : { "nom": "Ali", "age": 25 }, { "nom": "Sara", "age": 30 }
// Insertion
db.users.insertOne({
nom: "Omar",
age: 22,
hobbies: ["lecture", "sport"]
});
// Résultat : { "acknowledged": true, "insertedId": ObjectId("...") }
// Update
db.users.updateOne(
{ nom: "Ali" }, // Filtre
{ $set: { age: 26 } } // Modification
);
// Résultat : { "acknowledged": true, "modifiedCount": 1 }
// Delete
db.users.deleteOne({ nom: "Omar" });
// Résultat : { "acknowledged": true, "deletedCount": 1 }
Normalisation vs Dénormalisation
Concept
Description
Avantage / Inconvénient
Normalisation (SQL)
Organiser données pour éviter redondance (3NF, BCNF)
✓ Intégrité, pas de duplication ✗ Jointures complexes
Dénormalisation (NoSQL)
Dupliquer données pour lecture rapide
✓ Lecture rapide, pas de jointure ✗ Duplication, mise à jour complexe
Exemple - Normalisation (SQL) :
-- 1NF : Éliminer les groupes répétitifs
-- Table users: id, nom, adresse_id
-- Table adresses: id, rue, ville, cp
-- 2NF : Éliminer les dépendances partielles
-- Table commandes: id, user_id, date, montant
-- (Clé primaire = id, toutes les colonnes dépendent de id)
-- 3NF : Éliminer les dépendances transitives
-- Table users: id, nom, departement_id
-- Table departements: id, nom_departement, region
-- (La région dépend du département, pas du user)
-- Avantage : Pas de redondance
-- Si le département change de région, une seule mise à jour
-- Inconvénient : Requêtes avec jointures
SELECT u.nom, d.nom_departement, d.region
FROM users u
JOIN departements d ON u.departement_id = d.id;
Exemple - Dénormalisation (NoSQL) :
// Document MongoDB avec données embarquées
{
"_id": 1,
"nom": "Ali",
"departement": {
"id": 75,
"nom": "Paris",
"region": "Île-de-France"
},
"commandes": [
{ "id": 101, "montant": 150, "date": "2024-01-15" },
{ "id": 102, "montant": 80, "date": "2024-02-01" }
]
}
// Avantage : Lecture en une seule requête
db.users.find({ nom: "Ali" });
// Toutes les données sont là, pas de jointure
// Inconvénient : Mise à jour complexe
// Si la région change, il faut mettre à jour TOUS les users de Paris
db.users.updateMany(
{ "departement.id": 75 },
{ $set: { "departement.region": "Nouvelle Region" } }
);
// Duplication : Les données du département sont répétées pour chaque user
Indexation SQL
Type d'Index
Description
Exemple
PRIMARY KEY
Index unique + clusterisé (ordre physique)
Recherche rapide par ID
UNIQUE
Index garantissant unicité
Email unique, code produit
INDEX (B-Tree)
Index standard pour recherches rapides
CREATE INDEX idx_nom ON users(nom);
FULLTEXT
Index pour recherche texte
Recherche dans articles, descriptions
COMPOSITE
Index sur plusieurs colonnes
CREATE INDEX idx_nom_prenom ON users(nom, prenom);
Exemple - Indexation :
-- Créer un index simple
CREATE INDEX idx_ville ON users(ville);
-- Requête optimisée
SELECT * FROM users WHERE ville = 'Paris';
-- Sans index : Full table scan (lent)
-- Avec index : Recherche directe (rapide)
-- Index composite (ordre important !)
CREATE INDEX idx_ville_age ON users(ville, age);
-- Requêtes qui utilisent l'index composite :
SELECT * FROM users WHERE ville = 'Paris'; -- ✅ Utilise index
SELECT * FROM users WHERE ville = 'Paris' AND age > 25; -- ✅ Utilise index
SELECT * FROM users WHERE age > 25; -- ❌ N'utilise PAS l'index
-- Index unique
CREATE UNIQUE INDEX idx_email ON users(email);
-- Empêche les doublons d'email + accélère la recherche
-- Index FULLTEXT
CREATE FULLTEXT INDEX idx_contenu ON articles(contenu);
SELECT * FROM articles WHERE MATCH(contenu) AGAINST('javascript');
-- Voir les index
SHOW INDEX FROM users;
-- Supprimer un index
DROP INDEX idx_ville ON users;
EXPLAIN - Analyser les performances :
-- Avant l'index
EXPLAIN SELECT * FROM users WHERE ville = 'Paris';
-- +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
-- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
-- +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
-- | 1 | SIMPLE | users | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 10.00 | Using where |
-- +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
-- type = ALL : Full table scan (lent)
-- Après CREATE INDEX idx_ville ON users(ville);
EXPLAIN SELECT * FROM users WHERE ville = 'Paris';
-- type = ref : Utilise l'index (rapide)
-- key = idx_ville : Index utilisé
⚠️ Points clés pour QCM :
1. Ordre SQL : SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
2. WHERE vs HAVING : WHERE filtre les lignes (avant), HAVING filtre les groupes (après)
3. Jointures : INNER = intersection, LEFT = tout gauche + correspondances, RIGHT = tout droite + correspondances
4. NULL : Jamais = NULL, toujours IS NULL ou IS NOT NULL
5. SQL vs NoSQL : SQL = ACID, schéma rigide, vertical | NoSQL = BASE, schéma flexible, horizontal
6. DELETE vs TRUNCATE : DELETE = ligne par ligne (rollback possible), TRUNCATE = tout d'un coup (rapide, reset auto-increment)
Exemple - Ordre d'exécution complet :
-- Requête complète
SELECT u.ville, COUNT(*) as nb, AVG(u.age) as moyenne
FROM users u
WHERE u.age >= 18
GROUP BY u.ville
HAVING COUNT(*) > 1
ORDER BY moyenne DESC
LIMIT 2;
-- ORDRE D'EXÉCUTION :
-- 1. FROM users u → Charge la table
-- 2. WHERE u.age >= 18 → Filtre les lignes (exclut les mineurs)
-- 3. GROUP BY u.ville → Regroupe par ville
-- 4. HAVING COUNT(*) > 1 → Filtre les groupes (villes avec 1 seul user exclus)
-- 5. SELECT ... → Calcule COUNT et AVG pour chaque groupe
-- 6. ORDER BY moyenne DESC → Trie par moyenne décroissante
-- 7. LIMIT 2 → Garde les 2 premiers résultats
-- Résultat final :
-- +--------+----+---------+
-- | ville | nb | moyenne |
-- +--------+----+---------+
-- | Paris | 2 | 25.00 |
-- | Lyon | 2 | 28.00 |
-- +--------+----+---------+
🏗️ OOP & UML
Définitions OOP
Programmation Orientée Objet (POO/OOP) : Paradigme de programmation basé sur le concept d'"objets" qui contiennent des données (attributs) et du code (méthodes). Un objet est une instance d'une classe.
Classe vs Objet
Concept
Définition
Exemple
Classe
Modèle/blueprint qui définit les attributs et méthodes communs à un ensemble d'objets
Classe Voiture (définit couleur, marque, démarrer())
Objet
Instance concrète d'une classe créée en mémoire
Objet maVoiture (rouge, Toyota, instance spécifique)
Exemple - Classe et Instanciation :
// ===== DÉFINITION DE LA CLASSE (Le Plan/Blueprint) =====
class Voiture {
// Attributs (Données)
String marque;
String couleur;
// Méthode (Comportement)
void demarrer() {
System.out.println("Vroom ! La " + this.marque + " démarre.");
}
}
// ===== CRÉATION D'OBJETS (Instanciation) =====
public class Main {
public static void main(String[] args) {
// Création de l'objet 1 (Instance)
Voiture maVoiture = new Voiture();
maVoiture.marque = "Toyota"; // Assignation d'attribut
maVoiture.couleur = "Rouge";
// Création de l'objet 2 (Autre Instance)
Voiture taVoiture = new Voiture();
taVoiture.marque = "Peugeot";
// Utilisation
maVoiture.demarrer(); // Appel de méthode sur l'objet 1
}
}
// Résultat :
// Vroom ! La Toyota démarre.
Piliers OOP
Concept
Définition
Encapsulation
Contrôle d'accès (private/public/protected) - cacher les données et l'implémentation interne, exposer uniquement l'interface nécessaire
Héritage
Classe enfant hérite de classe parent (extends) - relation "est un". Permet la réutilisation du code et la création de hiérarchies
Polymorphisme
Même méthode, comportements différents selon l'objet. Permet de traiter des objets de classes différentes de manière uniforme
Abstraction
Modèles génériques (abstract/interface) - cacher la complexité et ne montrer que l'essentiel. Définit un contrat sans implémentation
Modificateurs d'Accès (Encapsulation)
Modificateur
Accès
Symbole UML
private
Uniquement dans la classe
- (moins)
public
Partout (défaut)
+ (plus)
protected
Classe + sous-classes
# (dièse)
package
Même package uniquement
~ (tilde)
Exemple - Encapsulation (Getters/Setters) :
class CompteBancaire {
// ATTRIBUT PRIVÉ : Non accessible directement de l'extérieur
// Mot clé : -solde (UML) / private (Code)
private double solde = 0;
// MÉTHODE PUBLIQUE : Interface pour lire (Getter)
// Mot clé : +getSolde (UML) / public (Code)
public double getSolde() {
return this.solde;
}
// MÉTHODE PUBLIQUE : Interface pour modifier de façon contrôlée (Setter)
public void deposer(double montant) {
if (montant > 0) {
this.solde += montant; // Modification interne autorisée
}
}
}
// Utilisation
CompteBancaire compte = new CompteBancaire();
// compte.solde = 1000; // ❌ ERREUR : solde has private access
compte.deposer(1000); // ✅ OK : Passe par l'interface publique
System.out.println("Solde : " + compte.getSolde());
// Résultat :
// Solde : 1000.0
Héritage (extends)
Syntaxe : class Enfant extends Parent
Caractéristiques :
- La classe enfant hérite de tous les attributs et méthodes
public et protected du parent
- Relation "est un" : un
Chien EST UN Animal
- Permet d'éviter la duplication de code
- Une classe peut hériter d'une seule classe (héritage simple)
Exemple - Héritage :
// ===== CLASSE PARENT (Généralisation) =====
class Animal {
String nom;
void manger() {
System.out.println(this.nom + " mange.");
}
}
// ===== CLASSE ENFANT (Spécialisation) =====
// Mot clé : extends (Héritage)
class Chien extends Animal {
// Hérite de 'nom' et 'manger()' automatiquement
void aboyer() {
System.out.println("Wouf !");
}
}
// Utilisation
Chien rex = new Chien();
rex.nom = "Rex"; // Attribut hérité de Animal
rex.manger(); // Méthode héritée de Animal
rex.aboyer(); // Méthode propre à Chien
// Résultat :
// Rex mange.
// Wouf !
Polymorphisme
Types de polymorphisme :
- Polymorphisme d'héritage : Redéfinition de méthodes (@Override) - comportement spécifique dans chaque classe fille
- Polymorphisme d'interface : Une classe implémente plusieurs interfaces
- Surcharge (overloading) : Même nom de méthode, paramètres différents
Exemple - Polymorphisme (Redéfinition/Override) :
class Animal {
void faireSon() {
System.out.println("L'animal fait un bruit.");
}
}
class Chat extends Animal {
// REDÉFINITION : Même signature, comportement différent
@Override
void faireSon() {
System.out.println("Miaou !");
}
}
class Chien extends Animal {
@Override
void faireSon() {
System.out.println("Wouf !");
}
}
// ===== UTILISATION POLYMORPHE =====
// Le type déclaré est Animal, mais l'objet réel change
Animal monAnimal;
monAnimal = new Chat();
monAnimal.faireSon(); // Appelle la méthode de Chat
monAnimal = new Chien();
monAnimal.faireSon(); // Appelle la méthode de Chien
// Résultat :
// Miaou !
// Wouf !
Abstraction (abstract / interface)
Concept
Définition
Usage
Classe Abstraite
Classe qui ne peut pas être instanciée, peut contenir méthodes abstraites (sans corps) et concrètes
Factoriser le code commun entre classes liées
Interface
Contrat qui définit uniquement des signatures de méthodes (sans implémentation)
Définir un comportement que plusieurs classes peuvent implémenter
Exemple - Interface et Implémentation :
// ===== INTERFACE (Le Contrat) =====
// Mot clé : interface
interface PeutVoler {
void voler(); // Signature uniquement, pas de corps
}
// ===== IMPLÉMENTATION =====
// Mot clé : implements
class Oiseau implements PeutVoler {
@Override
public void voler() {
System.out.println("L'oiseau vole dans le ciel.");
}
}
class Avion implements PeutVoler {
@Override
public void voler() {
System.out.println("L'avion vole avec des moteurs.");
}
}
// Utilisation
PeutVoler objetVolant1 = new Oiseau();
PeutVoler objetVolant2 = new Avion();
objetVolant1.voler();
objetVolant2.voler();
// Résultat :
// L'oiseau vole dans le ciel.
// L'avion vole avec des moteurs.
Diagramme de Classes UML
Structure d'une classe UML :
┌─────────────────┐
│ NomClasse │ ← Nom de la classe
├─────────────────┤
│ - attributPrivé │ ← Attributs (visibilité nom : type)
│ # protégé │
│ + public │
├─────────────────┤
│ + méthode() │ ← Méthodes (visibilité nom() : typeRetour)
│ - privée() │
└─────────────────┘
Relations UML - Diagramme de Classes
Relation
Symbole
Signification
Exemple
Héritage (Généralisation)
◄──── (flèche vide)
extends - "est un"
Chien ◄── Animal
Agrégation
◇──── (losange vide)
"a un" (faible) - partie vit indépendamment
Université ◇── Etudiant
Composition
◆──── (losange plein)
"est composé de" (fort) - partie meurt avec le tout
Maison ◆── Piece
Association
──────
Utilise / connaît - relation structurelle
Professeur ──── Cours
Dépendance
- - - -> (flèche pointillée)
Utilise temporairement
Client - - -> Commande
Exemple - Composition vs Agrégation :
// ===== COMPOSITION (Forte) =====
// Maison & Piece : Si Maison détruite → Pièces détruites
class Maison {
private Piece[] pieces; // Les pièces sont créées DANS la maison
Maison() {
this.pieces = new Piece[]{new Piece(), new Piece()};
}
}
// ===== AGRÉGATION (Faible) =====
// Université & Etudiant : Si Université fermée → Etudiants existent toujours
class Universite {
private List<Etudiant> etudiants;
void ajouterEtudiant(Etudiant e) {
this.etudiants.add(e); // L'étudiant est créé AILLEURS et passé en paramètre
}
}
// Mots clés Code :
// Composition : Création interne (new dans constructeur)
// Agrégation : Passage externe (setters ou constructeur)
Différence Agrégation vs Composition :
Agrégation (◇) : partie indépendante (Etudiant existe sans Université)
Composition (◆) : partie dépendante (Piece détruite avec Maison)
Diagramme Use Case (Cas d'Utilisation)
Éléments :
- Acteur : Entité externe qui interagit avec le système (représenté par un bonhomme stickman)
- Use Case : Fonctionnalité du système (ovale avec nom de l'action)
- Système : Frontière du système (rectangle)
Relation
Symbole
Signification
<<include>>
───▶ (flèche pointillée)
Toujours exécuté - le cas de base inclut obligatoirement l'autre
<<extend>>
◀─── (flèche pointillée inverse)
Conditionnel (optionnel) - extension sous certaines conditions
Exemple - Relation Include vs Extend :
USE CASE : "Retirer de l'argent"
├── <<include>> : "Vérifier Solde"
│ → Obligatoire. Pour retirer, on DOIT vérifier le solde.
│
└── <<extend>> : "Imprimer Reçu"
→ Optionnel. On peut retirer sans imprimer, seulement si le client le demande.
// Mots Clés UML :
// Include = "Tout le temps" (Dépendance obligatoire)
// Extend = "Parfois" (Optionnel sous condition)
Diagramme de Séquence
Définition : Représentation graphique qui décrit l'interaction des objets dans un système au fil du temps. Montre la séquence des messages échangés entre les objets.
Éléments clés :
- Lignes de vie : Lignes verticales représentant les objets participants
- Messages : Flèches horizontales entre lignes de vie (synchrone ▬▶, asynchrone -▶)
- Barres d'activation : Rectangles sur la ligne de vie indiquant quand l'objet est actif
- Message de retour : Flèche pointillée (--▶) indiquant la réponse
Usage : Modéliser un scénario d'utilisation spécifique, montrer l'ordre chronologique des interactions.
Exemple - Séquence "Authentification" :
// Représentation textuelle d'un diagramme de séquence
Acteur: Utilisateur
Objet1: InterfaceWeb
Objet2: AuthService
Objet3: BaseDeDonnees
Séquence :
1. Utilisateur --► InterfaceWeb : saisirLogin(mdp)
2. InterfaceWeb --► AuthService : verifier(identifiants)
3. AuthService --► BaseDeDonnees : trouverUtilisateur(email)
4. BaseDeDonnees --► AuthService : retourner(Utilisateur)
5. AuthService --► InterfaceWeb : retourner(Token) // Message retour pointillé
6. InterfaceWeb --► Utilisateur : afficherAccueil()
// Mots clés Séquence :
// Chronologie : Lecture de haut en bas.
// Activation : Barre verticale sur l'objet pendant qu'il traite la demande.
Diagramme d'États-Transitions (State Machine)
Définition : Visualise les états d'un automate à états finis. Représente le cycle de vie complet d'un objet ou système en montrant les états possibles et les transitions entre ces états.
Éléments :
- État : Rectangle aux coins arrondis (condition/moment dans la vie d'un objet)
- État initial : Cercle plein (début)
- État final : Cercle avec bordure (fin)
- Transition : Flèche entre états, étiquetée par
événement [garde] / action
Syntaxe transition : événement [condition] / activité
Exemple : appuyerBouton [lumièreAllumée==false] / allumerLumière
Exemple - Cycle de vie "Commande" :
États possibles : [EnCours], [Payée], [Expédiée], [Annulée]
(●) --créer--> [EnCours]
|
|-- payer --> [Payée]
| |
| |-- expédier --> [Expédiée] -- livrer --> (◉) Final
|
|-- annuler --> [Annulée] -- rembourser --> (◉) Final
// Exemple de Transition avec Garde :
// Événement : payer
// Garde : [montant > 0] (Condition à vérifier)
// Action : / envoyerEmailConfirmation
// Mots clés États :
// État : Situation stable (objet "attend").
// Transition : Passage instantané déclenché par un événement.
💻 C / Java / Python / PHP
C - Points Clés
C : Langage de programmation procédural de bas niveau, compilé, utilisé pour la programmation système et embarquée.
Principes Fondamentaux C
Concept
Description
Impact
Pointeurs
Variables stockant l'adresse mémoire d'une autre variable. Opérateurs & (adresse) et * (valeur pointée).
Gestion fine de la mémoire, passage par référence.
Gestion Mémoire
Manuelle. Le programmeur alloue (malloc) et libère (free). Pas de Garbage Collector.
Performance maximale, mais risques de fuites (leaks) et de segfaults.
Compilation
Code source (.c) → Compilation (gcc) → Exécutable binaire.
Rapide à l'exécution, dépendant de l'architecture.
Concept/Fonction
Détail
Exemple
printf()
Affichage formaté à l'écran. Utilise des spécificateurs : %d (int), %f (float), %s (string), %c (char)
printf("Age: %d", age);
scanf()
Lecture formatée depuis l'entrée standard. Nécessite l'opérateur & (adresse) pour les variables non-pointeurs
scanf("%d", &age);
main()
Point d'entrée obligatoire du programme. Retourne int (0 = succès, autre = erreur)
int main() { return 0; }
malloc()
Allocation dynamique de mémoire (non initialisée). Retourne un pointeur void* à caster
int* ptr = (int*)malloc(5 * sizeof(int));
calloc()
Allocation dynamique de mémoire initialisée à zéro. Prend 2 paramètres : nombre d'éléments et taille
int* ptr = (int*)calloc(5, sizeof(int));
realloc()
Redimensionne un bloc mémoire déjà alloué tout en conservant les données existantes
ptr = (int*)realloc(ptr, 10 * sizeof(int));
free()
Libère la mémoire allouée dynamiquement. Évite les fuites mémoire (memory leaks)
free(ptr); ptr = NULL;
strlen()
Retourne la longueur d'une chaîne (sans le caractère nul \0)
int len = strlen("Hello"); // 5
strcpy()
Copie une chaîne source vers une destination (attention aux débordements !)
strcpy(dest, src);
strcat()
Concatène (ajoute) une chaîne à la fin d'une autre
strcat(dest, " World");
strcmp()
Compare deux chaînes. Retourne 0 si égales, négatif si str1 < str2, positif si str1 > str2
if(strcmp(s1, s2) == 0)
fopen()
Ouvre un fichier. Modes : "r" (lecture), "w" (écriture), "a" (ajout)
FILE* f = fopen("data.txt", "r");
fclose()
Ferme un fichier ouvert. Libère les ressources associées
fclose(f);
fprintf() / fscanf()
Écriture/Lecture formatée dans un fichier (comme printf/scanf mais vers fichier)
fprintf(f, "%d", value);
atoi()
Convertit une chaîne en entier (int). Retourne 0 en cas d'erreur (peu fiable)
int n = atoi("123"); // 123
atof()
Convertit une chaîne en nombre à virgule flottante (double)
double d = atof("3.14");
rand() / srand()
Génère des nombres pseudo-aléatoires. srand() initialise le générateur (avec time(NULL))
srand(time(NULL)); int r = rand() % 100;
Exemple complet - Pointeurs et Allocation :
#include <stdio.h>
#include <stdlib.h>
int main() {
// 1. Allocation dynamique d'un tableau de 3 entiers
int *nombres = (int*)malloc(3 * sizeof(int));
if (nombres == NULL) {
printf("Erreur d'allocation\n");
return 1;
}
// 2. Remplissage via pointeur
nombres[0] = 10;
nombres[1] = 20;
nombres[2] = 30;
// 3. Affichage avec arithmétique de pointeurs
for (int i = 0; i < 3; i++) {
printf("Valeur %d: %d\n", i, *(nombres + i));
}
// 4. Libération de la mémoire OBLIGATOIRE
free(nombres);
return 0;
}
// Résultat :
// Valeur 0: 10
// Valeur 1: 20
// Valeur 2: 30
Exemple - Chaînes de caractères :
#include <stdio.h>
#include <string.h>
int main() {
char source[] = "Hello";
char destination[20]; // Attention à la taille !
// Copie
strcpy(destination, source);
printf("Copie: %s\n", destination);
// Concaténation
strcat(destination, " World");
printf("Concat: %s\n", destination);
// Longueur
printf("Longueur: %lu\n", strlen(destination));
// Comparaison
if (strcmp(destination, "Hello World") == 0) {
printf("Les chaînes sont identiques\n");
}
return 0;
}
// Résultat :
// Copie: Hello
// Concat: Hello World
// Longueur: 11
// Les chaînes sont identiques
Java - Points Clés
Java : Langage orienté objet, compilé en bytecode et exécuté sur la JVM (Java Virtual Machine). Portable ("Write Once, Run Anywhere").
Principes Fondamentaux Java
Concept
Description
Exemple
POO
Tout est objet (sauf types primitifs). Encapsulation, Héritage, Polymorphisme.
class Voiture extends Vehicule {}
JVM
Java Virtual Machine. Exécute le bytecode compilé (.class). Permet la portabilité.
javac Main.java → java Main
Garbage Collector
Gestion automatique de la mémoire. Libère les objets non référencés.
Pas besoin de free() comme en C.
== vs equals() :
== : compare les références (adresses mémoire) - utilise pour les types primitifs
equals() : compare le contenu des objets - obligatoire pour String et objets
Pour String : toujours utiliser equals() pour comparer le texte
Exemple - Piège des Strings :
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = "hello";
String s4 = "hello"; // Pool de strings
// Comparaison de références (adresses)
System.out.println(s1 == s2); // false (2 objets différents)
System.out.println(s3 == s4); // true (même objet dans le pool)
// Comparaison de contenu
System.out.println(s1.equals(s2)); // true (même contenu)
System.out.println(s1.equals(s3)); // true
Méthode/Concept
Action
Exemple
System.out.println()
Affiche une ligne à la console avec retour à la ligne
System.out.println("Hello");
Scanner
Classe pour lire l'entrée utilisateur. Méthodes : nextInt(), nextLine(), nextDouble()
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
String.length()
Retourne le nombre de caractères de la chaîne
int len = "Hello".length(); // 5
String.substring(0, 5)
Extrait une sous-chaîne (index début inclus, index fin exclus)
"Hello".substring(0, 2); // "He"
String.equals()
Compare le contenu de deux chaînes (retourne boolean)
if(s1.equals(s2))
String.charAt(i)
Retourne le caractère à l'index spécifié
char c = "Hello".charAt(0); // 'H'
String.indexOf()
Retourne l'index de la première occurrence d'une sous-chaîne (-1 si non trouvé)
"Hello".indexOf("l"); // 2
String.toUpperCase() / toLowerCase()
Convertit la chaîne en majuscules / minuscules
"hello".toUpperCase(); // "HELLO"
String.trim()
Supprime les espaces au début et à la fin de la chaîne
" hello ".trim(); // "hello"
String.split()
Divise la chaîne en tableau selon un délimiteur (regex)
"a,b,c".split(","); // ["a", "b", "c"]
String.replace()
Remplace toutes les occurrences d'un caractère/sous-chaîne
"Hello".replace('l', 'x'); // "Hexxo"
ArrayList<T>
Tableau dynamique redimensionnable. Import : java.util.ArrayList
ArrayList<String> list = new ArrayList<>();
ArrayList.add()
Ajoute un élément à la fin de la liste
list.add("Element");
ArrayList.add(index, element)
Insère un élément à l'index spécifié (décale les autres)
list.add(0, "Premier");
ArrayList.get(index)
Récupère l'élément à l'index spécifié
String s = list.get(0);
ArrayList.set(index, element)
Remplace l'élément à l'index spécifié
list.set(0, "Nouveau");
ArrayList.remove(index) / remove(Object)
Supprime l'élément à l'index ou l'objet spécifié
list.remove(0); list.remove("A");
ArrayList.size()
Retourne le nombre d'éléments dans la liste
int n = list.size();
ArrayList.clear()
Vide complètement la liste (supprime tous les éléments)
list.clear();
ArrayList.contains()
Vérifie si la liste contient l'élément spécifié (retourne boolean)
if(list.contains("A"))
ArrayList.indexOf()
Retourne l'index de la première occurrence (-1 si non trouvé)
int idx = list.indexOf("A");
Collections.sort()
Trie une liste (ordre naturel). Import : java.util.Collections
Collections.sort(list);
Integer.parseInt()
Convertit une String en int (lance NumberFormatException si invalide)
int n = Integer.parseInt("123");
Double.parseDouble()
Convertit une String en double
double d = Double.parseDouble("3.14");
Math.random()
Génère un nombre aléatoire entre 0.0 (inclus) et 1.0 (exclus)
int r = (int)(Math.random() * 100); // 0-99
Math.max() / Math.min()
Retourne le maximum/minimum de deux valeurs
int max = Math.max(5, 10); // 10
Exemple complet - Classes et ArrayList :
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
// Création d'une liste
ArrayList<String> langages = new ArrayList<>();
// Ajout
langages.add("Java");
langages.add("Python");
langages.add("C++");
// Affichage
System.out.println("Liste: " + langages);
// Accès et modification
langages.set(1, "JavaScript");
System.out.println("Modifié: " + langages.get(1));
// Tri
Collections.sort(langages);
System.out.println("Trié: " + langages);
// Boucle
for (String lang : langages) {
System.out.println("- " + lang);
}
// Taille et suppression
System.out.println("Taille: " + langages.size());
langages.remove("C++");
System.out.println("Après suppression: " + langages);
}
}
// Résultat :
// Liste: [Java, Python, C++]
// Modifié: JavaScript
// Trié: [C++, Java, JavaScript]
// - C++
// - Java
// - JavaScript
// Taille: 3
// Après suppression: [Java, JavaScript]
Python - Points Clés
Python : Langage de programmation interprété, orienté objet, avec une syntaxe claire et concise. Typage dynamique.
Principes Fondamentaux Python
Concept
Description
Exemple
Indentation
Définit les blocs de code (pas d'accolades {}). Obligatoire et stricte.
if True:
print("OK") # 4 espaces
Typage Dynamique
Le type est déterminé à l'exécution. Une variable peut changer de type.
x = 5 # int
x = "hello" # str
Everything is Object
Tout (nombres, fonctions, classes) est un objet avec des méthodes.
print(type(5)) # <class 'int'>
list vs tuple :
list [1, 2, 3] : Mutable (modifiable) - peut changer après création
tuple (1, 2, 3) : Immutable (non modifiable) - constante après création
Exemple - Mutable vs Immutable :
# LIST (Mutable)
liste = [1, 2, 3]
liste[0] = 99 # OK
liste.append(4) # OK
print(liste) # [99, 2, 3, 4]
# TUPLE (Immutable)
tup = (1, 2, 3)
# tup[0] = 99 # Erreur ! TypeError
# tup.append(4) # Erreur ! AttributeError
# Intérêt du tuple : clé de dictionnaire, retour multiple sécurisé
coordonnees = (10.5, 20.3)
x, y = coordonnees # Unpacking
print(f"x={x}, y={y}") # x=10.5, y=20.3
Fonction/Méthode
Action
Exemple
print()
Affiche des valeurs à l'écran. Accepte plusieurs arguments séparés par virgule
print("Hello", name)
input()
Lit une ligne depuis l'entrée standard (retourne toujours une String)
name = input("Nom: ")
len()
Retourne la longueur (nombre d'éléments) d'une liste, chaîne, tuple, dict, etc.
len([1, 2, 3]) # 3
type()
Retourne le type de l'objet (utile pour le débogage)
type(42) # <class 'int'>
int() / float() / str()
Conversion de types (casting). int() tronque la partie décimale
int("42") # 42
float("3.14") # 3.14
range(start, stop, step)
Génère une séquence d'entiers (stop exclus). Par défaut start=0, step=1
range(5) # 0,1,2,3,4
range(1, 10, 2) # 1,3,5,7,9
enumerate()
Retourne un itérable avec index et valeur (utile dans les boucles for)
for i, val in enumerate(['a','b']):
print(i, val)
zip()
Combine plusieurs listes en paires (s'arrête à la plus courte)
list(zip([1,2], ['a','b'])) # [(1,'a'), (2,'b')]
map()
Applique une fonction à chaque élément d'un itérable
list(map(str, [1, 2])) # ['1', '2']
filter()
Filtre les éléments selon une condition (fonction retournant bool)
list(filter(lambda x: x>0, [-1, 1, 2])) # [1, 2]
sum() / max() / min()
Opérations d'agrégation sur les itérables
sum([1, 2, 3]) # 6
max([1, 5, 2]) # 5
sorted()
Retourne une nouvelle liste triée (sans modifier l'original)
sorted([3, 1, 2]) # [1, 2, 3]
list.append(x)
Ajoute x à la FIN de la liste (modifie la liste en place)
lst = [1, 2]
lst.append(3) # [1, 2, 3]
list.insert(i, x)
Insère x à l'INDEX i (décale les éléments suivants)
lst.insert(0, 'a') # ['a', 1, 2, 3]
list.remove(x)
Supprime la première occurrence de x (erreur si x non trouvé)
lst.remove('a')
list.pop(i)
Supprime et retourne l'élément à l'index i (dernier par défaut)
x = lst.pop() # supprime dernier
list.sort()
Trie la liste en place (modifie l'original, retourne None)
lst.sort() # lst modifiée
list.reverse()
Inverse l'ordre des éléments en place
lst.reverse()
list.index(x)
Retourne l'index de la première occurrence de x
lst.index(2) # retourne position de 2
list.count(x)
Compte le nombre d'occurrences de x dans la liste
lst.count(1) # nombre de 1 dans lst
list.extend(iterable)
Ajoute tous les éléments d'un itérable à la fin de la liste
lst.extend([4, 5])
list.copy()
Crée une copie superficielle (shallow copy) de la liste
new_lst = lst.copy()
list.clear()
Vide complètement la liste (supprime tous les éléments)
lst.clear() # lst devient []
str.strip()
Enlève les espaces (et caractères spécifiés) du début et de la fin
" hello ".strip() # "hello"
str.split(sep)
Divise la chaîne en liste selon le séparateur (espace par défaut)
"a,b,c".split(",") # ['a', 'b', 'c']
str.join(iterable)
Joint les éléments d'un itérable avec la chaîne comme séparateur
",".join(['a', 'b']) # "a,b"
str.replace(old, new)
Remplace toutes les occurrences de old par new
"Hello".replace('l', 'x') # "Hexxo"
str.upper() / str.lower()
Convertit en majuscules / minuscules
"hello".upper() # "HELLO"
str.startswith() / str.endswith()
Vérifie si la chaîne commence/finit par une sous-chaîne
"hello".startswith("he") # True
dict.get(key, default)
Récupère la valeur d'une clé (retourne default si clé absente)
d.get('x', 0) # 0 si 'x' absent
dict.keys() / dict.values()
Retourne les clés / valeurs du dictionnaire
list(d.keys()) # liste des clés
dict.items()
Retourne les paires (clé, valeur) pour itération
for k, v in d.items():
open(file, mode)
Ouvre un fichier. Modes : 'r' (lecture), 'w' (écriture), 'a' (ajout)
f = open('data.txt', 'r')
file.read() / file.write()
Lit tout le contenu / Écrit une chaîne dans le fichier
content = f.read()
f.write("text")
file.readline()
Lit une ligne du fichier (avec le \n à la fin)
line = f.readline()
file.close()
Ferme le fichier (libère les ressources)
f.close()
with open(...) as f:
Gestionnaire de contexte - ferme automatiquement le fichier
with open('f.txt') as f:
content = f.read()
Exemple complet - Listes, Dicts et Slicing :
# SLICING (Découpage)
# syntaxe: liste[start:stop:step]
nombres = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(nombres[2:5]) # [2, 3, 4] (stop exclus)
print(nombres[:3]) # [0, 1, 2] (début jusqu'à 3)
print(nombres[7:]) # [7, 8, 9] (de 7 à la fin)
print(nombres[::2]) # [0, 2, 4, 6, 8] (un sur deux)
print(nombres[::-1]) # [9, 8, 7... 0] (inversé)
# LIST COMPREHENSION (Création concise)
carres = [x**2 for x in range(5)]
print(carres) # [0, 1, 4, 9, 16]
pairs = [x for x in range(10) if x % 2 == 0]
print(pairs) # [0, 2, 4, 6, 8]
# DICTIONNAIRE
etudiant = {"nom": "Ali", "age": 22, "cours": ["Math", "Info"]}
print(etudiant["nom"]) # "Ali"
print(etudiant.get("moyenne", 0)) # 0 (clé absente, défaut retourné)
# Itération
for cle, val in etudiant.items():
print(f"{cle}: {val}")
# Résultat :
# nom: Ali
# age: 22
# cours: ['Math', 'Info']
PHP - Points Clés
PHP : Langage de script côté serveur, spécialisé pour le développement web. S'exécute sur le serveur avant d'envoyer le HTML au client.
Principes Fondamentaux PHP
Concept
Description
Exemple
Syntaxe $
Toutes les variables commencent par le symbole dollar. Sensible à la casse.
$nom = "Ali";
Serveur → Client
PHP génère du HTML. Le client ne voit jamais le code PHP, seulement le résultat.
<?php echo "<b>Texte</b>"; ?>
Tableaux Associatifs
Clés personnalisées (string). Très utilisés (BDD, JSON, Config).
$user = ["nom" => "Ali", "age" => 25];
Concept/Fonction
Détail
Exemple
echo
Affiche une ou plusieurs chaînes (rapide, pas de retour de valeur). Accepte plusieurs paramètres séparés par virgule
echo "Hello", " ", "World";
print
Affiche une chaîne, retourne toujours 1 (plus lent qu'echo). Accepte un seul argument
print "Hello World";
var_dump()
Affiche les informations détaillées d'une variable (type et valeur). Utile pour le débogage
var_dump($array); // affiche type et contenu
print_r()
Affiche une représentation lisible d'une variable (pratique pour les tableaux)
print_r($array);
Variables
Toutes les variables commencent par le symbole $. Typage faible (type déterminé automatiquement)
$nom = "John";
$age = 25;
$_GET / $_POST
Tableaux superglobaux contenant les données envoyées par GET (URL) ou POST (formulaire)
$nom = $_POST['nom'];
$_SESSION
Tableau superglobal pour stocker des données de session (persistantes entre pages). Nécessite session_start()
session_start();
$_SESSION['user'] = 'John';
array_push()
Ajoute un ou plusieurs éléments à la FIN d'un tableau
array_push($arr, "a", "b");
array_pop()
Supprime et retourne le DERNIER élément du tableau
$last = array_pop($arr);
array_unshift()
Ajoute un ou plusieurs éléments au DÉBUT du tableau
array_unshift($arr, "premier");
array_shift()
Supprime et retourne le PREMIER élément du tableau
$first = array_shift($arr);
count() / sizeof()
Retourne le nombre d'éléments dans un tableau (count() est préféré)
$n = count($arr);
in_array()
Vérifie si une valeur existe dans le tableau (retourne boolean)
if(in_array("a", $arr))
array_search()
Cherche une valeur et retourne sa clé (ou false si non trouvé)
$key = array_search("a", $arr);
array_slice()
Extrait une portion de tableau (comme substring pour les tableaux)
$sub = array_slice($arr, 0, 3);
array_splice()
Supprime/remplace des éléments à une position arbitraire
array_splice($arr, 1, 2, ["x"]);
array_merge()
Fusionne un ou plusieurs tableaux en un seul
$combined = array_merge($a, $b);
array_map()
Applique une fonction de rappel à chaque élément du tableau
$squares = array_map(fn($x) => $x*$x, $nums);
array_filter()
Filtre les éléments selon une fonction de rappel
$even = array_filter($nums, fn($x) => $x % 2 == 0);
array_reduce()
Réduit un tableau à une valeur unique via une fonction cumulatrice
$sum = array_reduce($nums, fn($c, $i) => $c + $i, 0);
sort() / rsort()
Trie un tableau par valeurs en ordre croissant / décroissant (réindexe les clés)
sort($arr); // tri croissant
asort() / arsort()
Trie par valeurs en conservant les associations clé-valeur
asort($assoc);
ksort() / krsort()
Trie un tableau par clés (croissant / décroissant)
ksort($assoc);
explode()
Divise une chaîne en tableau selon un délimiteur
$arr = explode(",", "a,b,c"); // ["a", "b", "c"]
implode() / join()
Joint les éléments d'un tableau en une chaîne avec un séparateur
$str = implode(", ", $arr);
strlen()
Retourne la longueur d'une chaîne
$len = strlen("Hello"); // 5
strpos()
Retourne la position de la première occurrence d'une sous-chaîne (ou false)
$pos = strpos("Hello", "l"); // 2
stripos()
Comme strpos() mais insensible à la casse
$pos = stripos("Hello", "L"); // 2
substr()
Extrait une partie d'une chaîne (start, length)
$sub = substr("Hello", 0, 2); // "He"
str_replace()
Remplace toutes les occurrences d'une sous-chaîne par une autre
$s = str_replace("l", "x", "Hello"); // "Hexxo"
strtolower() / strtoupper()
Convertit une chaîne en minuscules / majuscules
$s = strtoupper("hello"); // "HELLO"
trim()
Supprime les espaces (et caractères spécifiés) du début et de la fin
$s = trim(" hello "); // "hello"
ltrim() / rtrim()
Supprime les espaces à gauche (début) / à droite (fin) uniquement
$s = ltrim(" hello");
PDO
Extension pour l'accès aux bases de données (MySQL, PostgreSQL, etc.). Supporte les requêtes préparées (sécurité contre SQL injection)
$pdo = new PDO("mysql:host=localhost;dbname=test", $user, $pass);
$pdo->prepare()
Prépare une requête SQL avec des paramètres nommés (?) ou positionnels (:nom)
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->bindParam()
Lie une variable à un paramètre de la requête préparée
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute()
Exécute la requête préparée
$stmt->execute();
$stmt->fetch()
Récupère la ligne suivante du résultat (PDO::FETCH_ASSOC pour tableau associatif)
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->fetchAll()
Récupère toutes les lignes du résultat dans un tableau
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$pdo->query()
Exécute une requête SQL et retourne un objet PDOStatement (pour SELECT simple)
$stmt = $pdo->query("SELECT * FROM users");
$pdo->exec()
Exécute une requête SQL et retourne le nombre de lignes affectées (pour INSERT/UPDATE/DELETE)
$count = $pdo->exec("DELETE FROM users WHERE id=1");
$pdo->lastInsertId()
Retourne l'ID auto-incrémenté généré par la dernière requête INSERT
$id = $pdo->lastInsertId();
json_encode()
Convertit une valeur PHP en chaîne JSON
$json = json_encode(['name' => 'John']);
json_decode()
Décode une chaîne JSON en valeur PHP (true pour tableau associatif)
$arr = json_decode($json, true);
file_get_contents()
Lit tout le contenu d'un fichier dans une chaîne
$content = file_get_contents('file.txt');
file_put_contents()
Écrit une chaîne dans un fichier (crée le fichier si inexistant)
file_put_contents('file.txt', 'Hello');
Exemple complet - Tableaux Associatifs et Boucles :
<?php
// Tableau associatif (clés string)
$produits = [
["nom" => "Laptop", "prix" => 999.99, "stock" => 5],
["nom" => "Souris", "prix" => 29.99, "stock" => 50],
["nom" => "Clavier", "prix" => 79.99, "stock" => 20]
];
// Parcourir avec foreach
foreach ($produits as $p) {
echo $p["nom"] . " - " . $p["prix"] . "€\n";
}
// Filtrer les produits chers
$chers = array_filter($produits, fn($p) => $p["prix"] > 50);
print_r(array_column($chers, "nom"));
// Calculer le stock total
$totalStock = array_sum(array_column($produits, "stock"));
echo "Stock total: $totalStock\n";
// JSON
$json = json_encode($produits);
echo $json; // [{"nom":"Laptop",...}]
?>
// Résultat :
// Laptop - 999.99€
// Souris - 29.99€
// Clavier - 79.99€
// Array ( [0] => Laptop [1] => Clavier )
// Stock total: 75
// [{"nom":"Laptop","prix":999.99,"stock":5},...]
Exemple - Connexion PDO et Requêtes Préparées :
<?php
// Configuration (normalement dans un fichier séparé)
$host = 'localhost';
$db = 'ma_base';
$user = 'root';
$pass = '';
try {
// Connexion
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Requête préparée (SÉCURISÉ contre injections SQL)
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(['email' => 'ali@test.com']);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
echo "Bienvenue " . htmlspecialchars($user['nom']);
} else {
echo "Utilisateur introuvable";
}
// Insertion
$sql = "INSERT INTO users (nom, email) VALUES (:nom, :email)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
'nom' => 'Sara',
'email' => 'sara@test.com'
]);
echo "Nouvel ID: " . $pdo->lastInsertId();
} catch (PDOException $e) {
echo "Erreur: " . $e->getMessage();
}
?>
⚛️ React.js
Définition : Bibliothèque JavaScript pour construire des interfaces utilisateur interactives (SPA) - Développée par Facebook (Meta). Utilise le Virtual DOM pour des mises à jour efficaces.
JSX Règles
Règle
Explication
Exemple Code
Parent unique
Un seul élément racine obligatoire
return (<div><h1>Titre</h1><p>Texte</p></div>);
Fragment
Utiliser <></> pour wrapper sans div
return (<><h1>A</h1><h1>B</h1></>);
className
Pas de class (mot réservé JS)
<div className="container">
Expressions JS
Variables et calculs entre {}
<p>{nom} a {age} ans</p>
CamelCase
Attributs en camelCase
<label htmlFor="input"> ou <button onClick={click}>
Composants
Type
Code Exemple
Fonctionnel (recommandé)
function Welcome({ name }) {
return <h1>Bonjour {name}</h1>;
}
// Utilisation : <Welcome name="John" />
Flèche (Arrow)
const Welcome = ({ name }) => {
return <h1>Bonjour {name}</h1>;
};
Classe (ancien)
class Welcome extends React.Component {
render() {
return <h1>Bonjour {this.props.name}</h1>;
}
}
Props vs State
Aspect
Props
State
Définition
Données passées de parent → enfant
Données internes au composant
Mutabilité
Immutables (lecture seule)
Mutable via setter
Code Exemple
// Parent
<User name="John" age={25} />
// Enfant
function User(props) {
return <p>{props.name}</p>;
}
const [count, setCount] = useState(0);
<button onClick={() => setCount(count + 1)}>
{count}
</button>
Hook useState - Exemples
Cas
Code
Piège / Note
Compteur simple
const [count, setCount] = useState(0);
<button onClick={() => setCount(count + 1)}>
{count}
</button>
setState est asynchrone !
Forme fonctionnelle (correct)
setCount(prev => prev + 1);
setCount(prev => prev + 1);
Quand la nouvelle valeur dépend de l'ancienne, toujours utiliser la forme fonctionnelle pour éviter les bugs
Objet state
const [user, setUser] = useState({
name: 'John',
age: 25
});
// Mise à jour
setUser({ ...user, age: 26 });
Spread operator (...) pour garder les anciennes valeurs !
Tableau state
const [items, setItems] = useState(['a', 'b']);
// Ajouter
setItems([...items, 'c']);
// Supprimer
setItems(items.filter(i => i !== 'b'));
Ne jamais modifier directement : items.push() ❌
Hook useEffect - Exemples
Cas d'usage
Code
Quand exécuté ?
Au montage seulement
useEffect(() => {
console.log('Composant monté');
}, []);
Une fois après le premier render (componentDidMount)
Surveillance variable
useEffect(() => {
console.log('count a changé:', count);
}, [count]);
À chaque changement de count
API / Fetch données
useEffect(() => {
fetch('https://api.com/users')
.then(r => r.json())
.then(data => setUsers(data));
}, []);
Une fois au montage (tableau vide)
Cleanup / Nettoyage
useEffect(() => {
const timer = setInterval(() => {...}, 1000);
return () => {
clearInterval(timer); // Cleanup
};
}, []);
Return = cleanup exécuté avant prochain effet ou démontage
Subscription
useEffect(() => {
const sub = websocket.subscribe(msg => {...});
return () => sub.unsubscribe();
}, []);
Essentiel pour éviter les fuites mémoire !
Hook useRef - Exemples
Usage
Code
Note
Référence DOM (focus)
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
Accès direct au nœud DOM
Valeur persistante
const renderCount = useRef(0);
renderCount.current++;
console.log('Renders:', renderCount.current);
Ne cause pas de re-render quand modifié
Stocker valeur précédente
const prevCount = useRef();
useEffect(() => {
prevCount.current = count;
}, [count]);
// prevCount.current = ancienne valeur
Comparaison ancienne/nouvelle valeur
Autres Hooks - Exemples
Hook
Code Exemple
Usage
useContext
const ThemeContext = createContext('light');
// Dans composant enfant :
const theme = useContext(ThemeContext);
// Retourne 'light' ou valeur du Provider
Partager données sans props drilling
useReducer
const [state, dispatch] = useReducer(
(state, action) => {
switch(action.type) {
case 'inc': return { count: state.count + 1 };
default: return state;
}
},
{ count: 0 }
);
// dispatch({ type: 'inc' })
Logique d'état complexe (Redux léger)
useMemo
const expensive = useMemo(() => {
return data.filter(x => x > 0).map(x => x * 2);
}, [data]);
Cache résultat calcul coûteux
useCallback
const handleClick = useCallback(() => {
console.log('clicked');
}, []); // Même référence entre renders
Cache fonction pour enfants optimisés
Rendu de Listes
Règle
Code Exemple
⚠️ Erreur à éviter
Key unique obligatoire
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
❌ key={index} - cause bugs si ordre change
Key stable
// ✅ ID de la base de données
key={item.id}
// ✅ Générer UUID si pas d'ID
key={crypto.randomUUID()}
La key doit être stable entre les renders
Gestion des Événements
Événement
Code Exemple
Note
onClick
<button onClick={() => alert('Cliqué!')}>
Cliquez
</button>
// OU avec fonction :
<button onClick={handleClick}>...
Pas de () dans onClick={} sauf si arrow function
onChange (input)
const [text, setText] = useState('');
<input
value={text}
onChange={(e) => setText(e.target.value)}
/>
e.target.value = valeur saisie
onSubmit (formulaire)
<form onSubmit={(e) => {
e.preventDefault(); // Empêche reload
console.log('Envoyé:', text);
}}>
<input ... />
<button type="submit">Envoyer</button>
</form>
e.preventDefault() obligatoire !
Event object
(e) => {
e.preventDefault(); // Annule action par défaut
e.stopPropagation(); // Stop bubbling
e.target.value; // Valeur élément
}
e = événement synthétique React
Formulaires Contrôlés vs Non-contrôlés
Type
Code
Avantage
Contrôlé (recommandé)
const [value, setValue] = useState('');
<input
value={value} // Contrôlé par React
onChange={(e) => setValue(e.target.value)}
/>
Validation temps réel, contrôle total, valeur garantie
Non-contrôlé
const inputRef = useRef(null);
<input ref={inputRef} />
// Lire valeur :
const value = inputRef.current.value;
Plus simple pour cas basiques, moins de code
Conditional Rendering
Méthode
Code
Usage
If simple
{isLoggedIn && <LogoutButton />}
Affiche si condition vraie
If-Else
{isLoggedIn
? <LogoutButton />
: <LoginButton />}
Choix entre deux éléments
Variable
let button;
if (isLoggedIn) {
button = <LogoutButton />;
} else {
button = <LoginButton />;
}
return <div>{button}</div>;
Logique complexe avant return
Règles des Hooks :
1. Appeler les hooks uniquement au niveau racine (pas dans boucles, conditions, ou fonctions imbriquées)
2. Appeler les hooks uniquement dans des composants React ou hooks personnalisés
3. L'ordre des hooks doit être identique à chaque render
🅰️ Angular
Définition : Framework TypeScript complet développé par Google pour applications d'entreprise (SPA). Architecture basée sur des composants réutilisables avec injection de dépendances native.
Commandes CLI Essentielles
Commande
Action
Exemple / Options
ng new projet
Créer nouvelle application
ng new mon-app --routing --style=scss
ng serve
Lancer serveur dev (hot reload)
ng serve --open --port 4200 (ou -o)
ng generate component nom
Générer composant (+ .html, .css, .spec.ts)
ng g c user-profile (g = generate)
ng generate service nom
Générer service injectable
ng g s services/auth
ng generate module nom
Générer module feature
ng g m admin --routing
ng build
Compiler pour production
ng build --configuration production (output dans /dist)
ng test
Exécuter tests unitaires (Vitest/Jasmine)
ng test --watch=false (une seule exécution)
ng add package
Installer et configurer librairie
ng add @angular/material
ng update
Mettre à jour Angular et dépendances
ng update @angular/core @angular/cli
Structure d'un Composant
Fichier
Rôle
Code Exemple
.ts
Logique TypeScript
@Component({
selector: 'app-hello',
templateUrl: './hello.component.html',
styleUrls: ['./hello.component.css']
})
export class HelloComponent {
title = 'Bonjour Angular!';
}
.html
Template (vue)
<div class="hello">
<h1>{{ title }}</h1>
</div>
.css/.scss
Styles scoped (uniquement ce composant)
.hello { color: blue; }
/* Scoped uniquement à ce composant */
Exemple complet - Composant simple :
// ===== user-card.component.ts =====
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-user-card',
template: `
<div class="card">
<h2>{{ user.name }}</h2>
<p>Email: {{ user.email }}</p>
</div>
`,
styles: ['.card { border: 1px solid #ccc; padding: 10px; }']
})
export class UserCardComponent {
@Input() user: { name: string; email: string } = { name: '', email: '' };
}
// ===== app.component.ts (Utilisation) =====
<app-user-card [user]="currentUser"></app-user-card>
// Résultat affiché :
// +----------------------+
// | Alice |
// | Email: alice@test.com|
// +----------------------+
Data Binding - 4 Types
Type
Syntaxe
Direction
Code Exemple
Interpolation
{{ expression }}
C → V
<h1>{{ title }}</h1> ou {{ 2 + 2 }}
Property
[property]="value"
C → V
<img [src]="imageUrl"> ou <button [disabled]="isDisabled">
Event
(event)="handler()"
V → C
<button (click)="onSave()"> ou <input (input)="onInput($event)">
Two-way
[(ngModel)]="property"
C ↔ V
<input [(ngModel)]="userName"> (nécessite FormsModule)
Mnémotechnique : "Banana in a box" [()] = Property [] + Event ()
Exemple pratique - Les 4 types de binding :
// ===== counter.component.ts =====
import { Component } from '@angular/core';
@Component({
selector: 'app-counter',
template: `
<!-- 1. Interpolation (Afficher) -->
<p>Compteur: {{ count }}</p>
<!-- 2. Property Binding (Définir propriété) -->
<button [disabled]="count === 0" (click)="decrement()">-</button>
<button [disabled]="count >= 10" (click)="increment()">+</button>
<!-- 3. Event Binding (Écouter) -->
<button (click)="reset()">Reset</button>
<!-- 4. Two-way Binding (Input utilisateur) -->
<label>Pas: <input type="number" [(ngModel)]="step"></label>
`
})
export class CounterComponent {
count = 0;
step = 1;
increment() { this.count += this.step; }
decrement() { this.count -= this.step; }
reset() { this.count = 0; }
}
// Test utilisateur :
// 1. Clic '+' -> Affiche "Compteur: 1"
// 2. Change "Pas" à 5 -> Clic '+' -> Affiche "Compteur: 6"
// 3. Clic '-' -> Affiche "Compteur: 1"
Directives Structurelles (*)
Directive
Usage
Code Exemple
*ngIf
Affichage conditionnel (retire du DOM si faux)
<div *ngIf="isLogged">Bienvenue</div>
<!-- Avec else -->
<div *ngIf="isLogged; else loginTpl">Bienvenue</div>
<ng-template #loginTpl>Connectez-vous</ng-template>
*ngFor
Boucle sur collection
<ul>
<li *ngFor="let user of users; let i = index">
{{ i + 1 }}. {{ user.name }}
</li>
</ul>
[ngClass]
Classes CSS dynamiques
<div [ngClass]="{'active': isActive, 'disabled': isDisabled}">
<div [ngClass]="['class1', 'class2']">
[ngStyle]
Styles inline dynamiques
<div [ngStyle]="{'color': 'red', 'font-size.px': 14}">
Exemple complet - Liste avec *ngFor et *ngIf :
// ===== user-list.component.ts =====
users = [
{ id: 1, name: 'Alice', active: true },
{ id: 2, name: 'Bob', active: false },
{ id: 3, name: 'Charlie', active: true }
];
// Template
<ul>
<li *ngFor="let user of users; trackBy: trackById"
[ngClass]="{'active-user': user.active, 'inactive-user': !user.active}">
{{ user.name }}
<span *ngIf="user.active; else inactiveBadge">
✅ Actif
</span>
<ng-template #inactiveBadge>
❌ Inactif
</ng-template>
</li>
</ul>
// Logique de tracking (optimisation performance)
trackById(index: number, user: any): number {
return user.id;
}
// Résultat :
// • Alice ✅ Actif (classe .active-user)
// • Bob ❌ Inactif (classe .inactive-user)
// • Charlie ✅ Actif (classe .active-user)
Nouvelle Syntaxe Control Flow (Angular 17+)
Directive
Ancien (*ng)
Nouveau (@)
Condition
*ngIf
@if (isLogged) {
<p>Bienvenue</p>
} @else {
<p>Connectez-vous</p>
}
Boucle
*ngFor
@for (item of items; track item.id) {
<li>{{ item.name }}</li>
} @empty {
<p>Aucun élément</p>
}
Switch
[ngSwitch]
@switch (role) {
@case ('admin') { <p>Admin</p> }
@case ('user') { <p>User</p> }
@default { <p>Guest</p> }
}
Exemple - Syntaxe moderne Angular 17+ :
// Component
role = 'admin';
items = [
{ id: 1, name: 'Laptop' },
{ id: 2, name: 'Phone' }
];
// Template
@switch (role) {
@case ('admin') {
<div class="admin-panel">Panneau Admin</div>
}
@case ('user') {
<div class="user-panel">Panneau User</div>
}
@default {
<p>Veuillez vous connecter</p>
}
}
@for (item of items; track item.id) {
<div>{{ item.name }}</div>
} @empty {
<p>Aucun produit disponible</p>
}
// Résultat :
// Panneau Admin
// Laptop
// Phone
Cycle de Vie - Hooks
Hook
Moment
Code Exemple
ngOnInit()
Après création du composant (initialisation)
ngOnInit() {
// Appels API, setup initial
this.loadData();
}
ngOnChanges()
Quand les @Input() changent
ngOnChanges(changes: SimpleChanges) {
console.log(changes['userName'].currentValue);
}
ngOnDestroy()
Avant destruction (nettoyage)
ngOnDestroy() {
this.subscription.unsubscribe(); // ⚠️ Important !
}
Exemple - Ordre d'exécution des Hooks :
import { Component, Input, OnChanges, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-lifecycle',
template: '<p>Lifecycle Demo</p>'
})
export class LifecycleComponent implements OnChanges, OnInit, OnDestroy {
@Input() data: string = '';
// 1. Appelé à chaque changement de @Input
ngOnChanges() {
console.log('1. ngOnChanges - Input modifié');
}
// 2. Appelé une seule fois après le premier ngOnChanges
ngOnInit() {
console.log('2. ngOnInit - Composant initialisé');
}
// 3. Appelé juste avant la destruction du composant
ngOnDestroy() {
console.log('3. ngOnDestroy - Composant détruit');
}
}
// Console lors de la création :
// "1. ngOnChanges - Input modifié"
// "2. ngOnInit - Composant initialisé"
// Console lors de la navigation vers une autre page :
// "3. ngOnDestroy - Composant détruit"
Communication Parent ↔ Enfant
Direction
Décorateur
Code Exemple
Parent → Enfant
@Input()
// Enfant
@Input() userName: string;
// Parent
<app-enfant [userName]="parentName"></app-enfant>
Enfant → Parent
@Output()
// Enfant
@Output() notify = new EventEmitter<string>();
send() { this.notify.emit('message'); }
// Parent
<app-enfant (notify)="onNotify($event)"></app-enfant>
Exemple complet - Parent/Enfant :
// ===== child.component.ts =====
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<div>
<h3>Enfant</h3>
<p>Message du parent: {{ message }}</p>
<button (click)="replyToParent()">Répondre</button>
</div>
`
})
export class ChildComponent {
@Input() message: string = ''; // Reçoit du parent
@Output() response = new EventEmitter<string>(); // Envoie au parent
replyToParent() {
this.response.emit('Salut Papa !');
}
}
// ===== parent.component.ts =====
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<div>
<h2>Parent</h2>
<p>Réponse de l'enfant: {{ childResponse }}</p>
<!-- Envoi de données [message] / Réception (response) -->
<app-child
[message]="'Bonjour Fils'"
(response)="onResponse($event)">
</app-child>
</div>
`
})
export class ParentComponent {
childResponse = '';
onResponse(msg: string) {
this.childResponse = msg;
}
}
// Résultat affiché :
// Parent
// Réponse de l'enfant: Salut Papa ! (après clic)
// Enfant
// Message du parent: Bonjour Fils
// [Répondre]
Services et Dependency Injection
Concept
Code Exemple
Note
Création Service
@Injectable({
providedIn: 'root' // Singleton global
})
export class UserService {
getUsers() {
return ['Alice', 'Bob'];
}
}
providedIn: 'root' = une seule instance
Injection (classique)
constructor(private userService: UserService) {}
Pattern recommandé
Injection (moderne)
private userService = inject(UserService);
Angular 14+
Exemple complet - Service et Injection :
// ===== user.service.ts =====
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root' // Singleton disponible partout
})
export class UserService {
private users = [
{ id: 1, name: 'Alice', role: 'Admin' },
{ id: 2, name: 'Bob', role: 'User' }
];
getUsers(): Observable<any[]> {
return of(this.users); // Simule un appel HTTP
}
}
// ===== app.component.ts =====
import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'app-root',
template: `
<ul>
<li *ngFor="let user of users">{{ user.name }} ({{ user.role }})</li>
</ul>
`
})
export class AppComponent implements OnInit {
users: any[] = [];
// Injection du service via le constructeur
constructor(private userService: UserService) {}
ngOnInit() {
this.userService.getUsers().subscribe(data => {
this.users = data;
});
}
}
Routing
Concept
Code Exemple
Configuration routes
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'users/:id', component: UserDetailComponent },
{ path: '**', component: NotFoundComponent } // Wildcard dernier !
];
Navigation template
<a routerLink="/home">Accueil</a>
<a [routerLink]="['/users', userId]">Détail</a>
<a routerLink="/home" routerLinkActive="active">Accueil</a>
Navigation programmatique
constructor(private router: Router) {}
goToDetail(id: number) {
this.router.navigate(['/users', id]);
}
Exemple - Mise en place du Router :
// ===== app-routing.module.ts =====
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { UserDetailComponent } from './user-detail/user-detail.component';
const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'user/:id', component: UserDetailComponent }, // Route paramétrée
{ path: '**', redirectTo: 'home' } // Fallback
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
// ===== app.component.html =====
<nav>
<a routerLink="/home" routerLinkActive="active">Home</a>
<a routerLink="/user/1">User 1</a>
</nav>
<router-outlet></router-outlet>
<!-- Les composants s'affichent ici -->
// ===== user-detail.component.ts (Lecture paramètre) =====
import { ActivatedRoute } from '@angular/router';
constructor(private route: ActivatedRoute) {}
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
console.log('ID utilisateur:', id); // "1"
}
HTTP Client - Requêtes
Méthode
Code Exemple
GET
getUsers(): Observable<User[]> {
return this.http.get<User[]>('https://api.example.com/users');
}
POST
createUser(user: User): Observable<User> {
return this.http.post<User>('/api/users', user);
}
PUT
updateUser(id: number, user: User): Observable<User> {
return this.http.put<User>(`/api/users/${id}`, user);
}
DELETE
deleteUser(id: number): Observable<void> {
return this.http.delete<void>(`/api/users/${id}`);
}
Subscribe
this.api.getUsers().subscribe({
next: data => this.users = data,
error: err => console.error(err),
complete: () => console.log('Terminé')
});
Exemple complet - Service HTTP :
// ===== api.service.ts =====
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class ApiService {
private apiUrl = 'https://jsonplaceholder.typicode.com/users';
constructor(private http: HttpClient) {}
getUsers(): Observable<any[]> {
return this.http.get<any[]>(this.apiUrl);
}
createUser(user: any): Observable<any> {
return this.http.post<any>(this.apiUrl, user);
}
}
// ===== app.component.ts =====
import { Component, OnInit } from '@angular/core';
import { ApiService } from './api.service';
@Component({
selector: 'app-root',
template: `
<ul>
<li *ngFor="let user of users">{{ user.name }}</li>
</ul>
<button (click)="addUser()">Ajouter</button>
`
})
export class AppComponent implements OnInit {
users: any[] = [];
constructor(private api: ApiService) {}
ngOnInit() {
this.loadUsers();
}
loadUsers() {
this.api.getUsers().subscribe({
next: (data) => this.users = data,
error: (err) => console.error('Erreur API:', err)
});
}
addUser() {
this.api.createUser({ name: 'Nouveau' }).subscribe(() => {
console.log('Utilisateur créé');
});
}
}
Observable vs Async Pipe
Méthode
Code
Avantage/Inconvénient
Manual Subscribe
users: User[] = [];
sub: Subscription;
ngOnInit() {
this.sub = this.api.getUsers().subscribe(
data => this.users = data
);
}
ngOnDestroy() {
this.sub.unsubscribe(); // Obligatoire !
}
Contrôle total, mais unsubscribe manuel obligatoire
Async Pipe
// Component
users$ = this.api.getUsers();
// Template
<li *ngFor="let user of users$ | async">{{ user.name }}</li>
// Ou avec alias
<div *ngIf="users$ | async as users">
{{ users.length }} utilisateurs
</div>
Auto-subscribe/unsubscribe, code plus propre
Comparaison - Manual vs Async Pipe :
// ❌ MÉTHODE 1 : Manuel (Risque de fuite mémoire)
export class UsersComponent implements OnInit, OnDestroy {
users: User[] = [];
private sub?: Subscription;
ngOnInit() {
this.sub = this.http.get<User[]>('/api/users').subscribe(data => {
this.users = data; // Stockage manuel
});
}
ngOnDestroy() {
this.sub?.unsubscribe(); // Nettoyage manuel OBLIGATOIRE
}
}
// ✅ MÉTHODE 2 : Async Pipe (Recommandé)
export class UsersComponent {
// Déclaration simple de l'Observable
users$ = this.http.get<User[]>('/api/users');
constructor(private http: HttpClient) {}
}
// Template (users$ | async)
<ul>
<li *ngFor="let user of users$ | async">
{{ user.name }}
</li>
</ul>
// Avantage Async Pipe :
// 1. Subscribe automatique à l'initialisation
// 2. Unsubscribe automatique à la destruction
// 3. Met à jour la vue dès que les données arrivent
// 4. Pas de variable intermédiaire nécessaire
Pipes (Filtres)
Pipe
Description
Exemple
date
Formater dates
{{ today | date:'dd/MM/yyyy' }} → 13/03/2026
uppercase
Majuscules
{{ 'hello' | uppercase }} → HELLO
lowercase
Minuscules
{{ 'HELLO' | lowercase }} → hello
currency
Format monétaire
{{ price | currency:'EUR' }} → €100.00
decimal
Nombre formaté
{{ 3.14159 | number:'1.2-2' }} → 3.14
percent
Pourcentage
{{ 0.25 | percent }} → 25%
json
Debug (affiche objet)
{{ user | json }}
async
Subscribe auto Observable/Promise
{{ users$ | async }}
Exemple - Chaînage de Pipes :
// Component
today = new Date();
price = 99.99;
user = { name: 'Alice', role: 'admin' };
// Template
<p>Date: {{ today | date:'fullDate' }}</p>
<p>Date courte: {{ today | date:'dd/MM/yy' | uppercase }}</p>
<p>Prix: {{ price | currency:'EUR':'symbol':'1.2-2' }}</p>
<p>User: {{ user | json }}</p>
// Résultat :
// Date: vendredi 13 mars 2026
// Date courte: 13/03/26
// Prix: €99.99
// User: { "name": "Alice", "role": "admin" }
Signals (Angular 16+)
Concept
Code Exemple
Description
signal()
const count = signal(0);
count.set(5);
count.update(v => v + 1);
console.log(count()); // 6
Valeur réactive mutable
computed()
const double = computed(() => count() * 2);
Signal dérivé (lazy evaluation)
effect()
effect(() => {
console.log('Count:', count());
});
Effet de bord quand signal change
Exemple - Signals complet :
import { Component, signal, computed, effect } from '@angular/core';
@Component({
selector: 'app-counter',
template: `
<p>Compteur: {{ count() }}</p>
<p>Double: {{ double() }}</p>
<button (click)="increment()">+</button>
`
})
export class CounterComponent {
// 1. Signal (état réactif)
count = signal(0);
// 2. Computed (valeur dérivée automatique)
double = computed(() => this.count() * 2);
constructor() {
// 3. Effect (réaction aux changements)
effect(() => {
console.log(`Le compteur a changé: ${this.count()}`);
});
}
increment() {
this.count.update(v => v + 1);
}
}
// Flow :
// 1. Click -> count devient 1
// 2. double se met à jour automatiquement -> 2
// 3. effect() s'exécute -> console: "Le compteur a changé: 1"
Formulaires
Type
Description
Code Exemple
Template-driven
Simple, logique dans template
<form #form="ngForm" (ngSubmit)="onSubmit(form)">
<input name="name" [(ngModel)]="user.name" required>
<button [disabled]="!form.valid">Submit</button>
</form>
Reactive Forms
Complexe, logique dans component
// Component
form = new FormGroup({
name: new FormControl('', Validators.required),
email: new FormControl('', [Validators.required, Validators.email])
});
// Template
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input formControlName="name">
</form>
Exemple - Reactive Forms complet :
// ===== user-form.component.ts =====
import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-user-form',
template: `
<form [formGroup]="userForm" (ngSubmit)="onSubmit()">
<!-- Champ Nom -->
<label>Nom:
<input type="text" formControlName="name">
</label>
<p *ngIf="userForm.get('name')?.invalid && userForm.get('name')?.touched">
Le nom est requis.
</p>
<!-- Champ Email -->
<label>Email:
<input type="email" formControlName="email">
</label>
<p *ngIf="userForm.get('email')?.errors?.['email']">
Email invalide.
</p>
<button type="submit" [disabled]="userForm.invalid">Envoyer</button>
</form>
<pre>{{ userForm.value | json }}</pre>
`
})
export class UserFormComponent {
userForm = new FormGroup({
name: new FormControl('', [Validators.required, Validators.minLength(3)]),
email: new FormControl('', [Validators.required, Validators.email])
});
onSubmit() {
if (this.userForm.valid) {
console.log('Form Submitted:', this.userForm.value);
// Résultat : { name: "Alice", email: "alice@test.com" }
}
}
}
⚠️ Points importants :
1. Toujours faire unsubscribe() dans ngOnDestroy() pour éviter les fuites mémoire (sauf avec async pipe) !
2. providedIn: 'root' (minuscule) pour singleton global
3. Wildcard ** TOUJOURS en dernier dans les routes !
4. trackBy ou track obligatoire pour les boucles (optimisation)
5. FormsModule requis pour [(ngModel)]
🍃 Spring Boot
Définition : Framework Java permettant de créer rapidement des applications autonomes avec auto-configuration et serveur embarqué (Tomcat par défaut).
Annotations Essentielles - Code Exemples
Annotation
Rôle
Code Exemple
@SpringBootApplication
Point d'entrée principal (combine @Configuration, @EnableAutoConfiguration, @ComponentScan)
@SpringBootApplication
public class MonApplication {
public static void main(String[] args) {
SpringApplication.run(MonApplication.class, args);
}
}
@RestController
Endpoints API retournant JSON (combine @Controller + @ResponseBody)
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping
public List<User> getUsers() {
return userService.findAll();
}
}
@Controller
Retourne des vues HTML (templates Thymeleaf/JSP)
@Controller
public class PageController {
@GetMapping("/home")
public String home(Model model) {
model.addAttribute("msg", "Hello");
return "home"; // home.html
}
}
@Service
Logique métier (couche service)
@Service
public class UserService {
@Autowired
private UserRepository repo;
public User findById(Long id) {
return repo.findById(id).orElse(null);
}
}
@Repository
Accès aux données (CRUD) - traduit les exceptions SQL en Spring DataAccessException
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByName(String name);
}
@Entity
Classe = table BDD (JPA)
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
@Autowired
Injection automatique de dépendances (par constructeur recommandé)
// Injection par constructeur (recommandé)
@Service
public class UserService {
private final UserRepository repo;
@Autowired
public UserService(UserRepository repo) {
this.repo = repo;
}
}
@Transactional
Gestion transactionnelle (rollback si échec)
@Transactional
public void transferMoney(Long from, Long to, Double amount) {
accountRepo.debit(from, amount);
accountRepo.credit(to, amount);
// Rollback automatique si exception
}
Exemple complet - Structure d'une application :
// 1. ENTITY (Modèle de données)
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
// Getters, Setters, Constructeurs
}
// 2. REPOSITORY (Accès données)
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Requête dérivée automatiquement
Optional<User> findByEmail(String email);
}
// 3. SERVICE (Logique métier)
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> getAllUsers() {
return userRepository.findAll();
}
public User createUser(User user) {
return userRepository.save(user);
}
}
// 4. CONTROLLER (API REST)
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping
public List<User> getUsers() {
return userService.getAllUsers();
}
}
// Résultat (JSON retourné par GET /api/users) :
// [
// { "id": 1, "name": "Alice" },
// { "id": 2, "name": "Bob" }
// ]
Annotations Web - Mapping HTTP
Annotation
HTTP Method
Code Exemple
@GetMapping
GET
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return service.findById(id);
}
@PostMapping
POST
@PostMapping
public User createUser(@RequestBody User user) {
return service.save(user);
}
@PutMapping
PUT (idempotent)
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
return service.update(id, user);
}
@DeleteMapping
DELETE
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
service.delete(id);
}
@PatchMapping
PATCH (partiel)
@PatchMapping("/{id}")
public User patchUser(@PathVariable Long id, @RequestBody Map<String, Object> updates) {
return service.partialUpdate(id, updates);
}
Exemple - CRUD Complet avec Endpoints :
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService service;
// GET /api/products
@GetMapping
public List<Product> getAll() {
return service.findAll();
}
// GET /api/products/1
@GetMapping("/{id}")
public ResponseEntity<Product> getById(@PathVariable Long id) {
return service.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
// POST /api/products
@PostMapping
public Product create(@RequestBody Product product) {
return service.save(product);
}
// PUT /api/products/1
@PutMapping("/{id}")
public Product update(@PathVariable Long id, @RequestBody Product product) {
product.setId(id);
return service.save(product);
}
// DELETE /api/products/1
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
service.delete(id);
return ResponseEntity.noContent().build();
}
}
// Tests :
// POST /api/products body: {"name":"Laptop", "price":999.99}
// Résultat : 201 Created, {"id": 1, "name": "Laptop", "price": 999.99}
// GET /api/products/999 (inexistant)
// Résultat : 404 Not Found
Paramètres de Requête
Annotation
Usage
Code Exemple
@PathVariable
Variable dans l'URL /users/{id}
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) { ... }
// URL: /users/123
@RequestParam
Paramètre de requête ?key=value
@GetMapping("/users")
public List<User> search(@RequestParam String name) { ... }
// URL: /users?name=John
@RequestBody
Corps de la requête (JSON → Objet)
@PostMapping("/users")
public User create(@RequestBody User user) { ... }
// JSON: {"name": "John", "email": "john@test.com"}
@RequestHeader
Valeur d'un header HTTP
@GetMapping("/header")
public String getHeader(@RequestHeader("X-Api-Key") String apiKey) { ... }
Exemple - Combinaison des paramètres :
@RestController
@RequestMapping("/api")
public class QueryController {
// Combinaison PathVariable + RequestParam
// GET /api/users/1/posts?published=true
@GetMapping("/users/{userId}/posts")
public List<Post> getUserPosts(
@PathVariable Long userId,
@RequestParam(required = false, defaultValue = "false") boolean published
) {
return postService.findByUserAndStatus(userId, published);
}
// RequestParam avec valeur par défaut
// GET /api/articles?page=2
@GetMapping("/articles")
public Page<Article> getArticles(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size
) {
return articleService.findAll(page, size);
}
}
// Test : GET /api/articles?page=1&size=5
// Résultat : Page 1 avec 5 éléments par page
Architecture Couches
Couche
Rôle
Code Exemple
Controller
Reçoit requêtes HTTP, valide entrées, appelle service
@RestController
public class UserController {
@Autowired
private UserService service;
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return ResponseEntity.ok(service.findById(id));
}
}
Service
Logique métier, transactions, règles métier
@Service
@Transactional
public class UserService {
public User createUser(UserDTO dto) {
// Validation métier
if (emailExists(dto.getEmail())) {
throw new RuntimeException("Email existe déjà");
}
return userRepo.save(new User(dto));
}
}
Repository
Accès données, requêtes SQL/JPQL
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT u FROM User u WHERE u.email = :email")
Optional<User> findByEmail(@Param("email") String email);
}
Entity/Model
Représentation BDD (tables)
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String password;
}
Flux de données Architecture 3-Tiers :
Client (React/Angular/Mobile)
|
| HTTP Request (JSON)
v
+------------------+
| Controller | @RestController
| (Validation) | Gère les endpoints
+--------+---------+
|
| Appel méthode Java
v
+------------------+
| Service | @Service
| (Logique Métier) | Transactions, Règles
+--------+---------+
|
| Appel JPA
v
+------------------+
| Repository | @Repository / JpaRepository
| (Accès Données) | Génère SQL
+--------+---------+
|
| JDBC
v
+------------------+
| Database | MySQL / PostgreSQL
+------------------+
Méthodes HTTP - Comparaison
Méthode
Action
Idempotent
Exemple
GET
Récupérer des données
✅ Oui
GET /users/123 → Récupère user 123
POST
Créer une ressource
❌ Non
POST /users + body → Crée nouveau user
PUT
Mettre à jour complet (remplace tout)
✅ Oui
PUT /users/123 + body complet → Remplace user 123
PATCH
Mettre à jour partiel (champs spécifiques)
❌ Non
PATCH /users/123 + {email: "new@test.com"}
DELETE
Supprimer une ressource
✅ Oui
DELETE /users/123 → Supprime user 123
Exemple - Différence PUT vs PATCH :
// Ressource existante :
// { "id": 1, "name": "Alice", "email": "alice@old.com", "role": "user" }
// 1. PUT /users/1 (Remplacement COMPLET)
// Body envoyé :
{
"name": "Alice Updated",
"email": "alice@new.com",
"role": "admin"
}
// Résultat : Tout est remplacé. Si on oublie "role", il devient null.
// 2. PATCH /users/1 (Mise à jour PARTIELLE)
// Body envoyé :
{
"email": "alice@new.com"
}
// Résultat : Seul l'email change.
// { "id": 1, "name": "Alice", "email": "alice@new.com", "role": "user" }
JPA - Relations
Annotation
Relation
Code Exemple
@OneToOne
Un-à-un (User ↔ Profile)
@Entity
public class User {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "profile_id")
private Profile profile;
}
@OneToMany
Un-à-plusieurs (côté "un" - User → Orders)
@Entity
public class User {
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Order> orders;
}
@ManyToOne
Plusieurs-à-un (côté "plusieurs", propriétaire FK)
@Entity
public class Order {
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
@ManyToMany
Plusieurs-à-plusieurs (User ↔ Roles)
@Entity
public class User {
@ManyToMany
@JoinTable(
name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles;
}
Exemple - Relation OneToMany bidirectionnelle :
// ===== CÔTÉ "UN" (Parent) =====
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
private List<Product> products = new ArrayList<>();
// Méthode helper pour synchroniser
public void addProduct(Product product) {
products.add(product);
product.setCategory(this);
}
}
// ===== CÔTÉ "PLUSIEURS" (Enfant - Propriétaire de la clé étrangère) =====
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id") // Colonne FK dans table product
private Category category;
}
// Utilisation :
Category electronics = new Category();
electronics.setName("Electronics");
Product laptop = new Product();
laptop.setName("Laptop");
electronics.addProduct(laptop); // Synchronise les deux côtés
categoryRepo.save(electronics); // Sauvegarde les deux grâce à CASCADE.ALL
// Tables SQL créées :
// categories (id, name)
// products (id, name, category_id)
FetchType - Comparaison
Type
Comportement
Code Exemple
Usage
LAZY
Chargement différé (à la demande) - optimisation mémoire
@OneToMany(fetch = FetchType.LAZY)
Par défaut pour @OneToMany et @ManyToMany. Données chargées uniquement quand accédées.
EAGER
Chargement immédiat (tout en une requête) - consommateur de ressources
@ManyToOne(fetch = FetchType.EAGER)
Par défaut pour @ManyToOne et @OneToOne. Données chargées avec l'entité parent.
Exemple - Problème N+1 et LAZY Loading :
// Configuration : @OneToMany(fetch = FetchType.LAZY)
@Entity
public class Author {
@OneToMany(mappedBy = "author")
private List<Book> books;
}
// === SCÉNARIO LAZY (Recommandé) ===
Author author = authorRepo.findById(1L);
// SQL exécuté : SELECT * FROM authors WHERE id = 1
// Les livres ne sont PAS encore chargés
author.getBooks(); // Déclenche UNE requête supplémentaire
// SQL exécuté : SELECT * FROM books WHERE author_id = 1
// === PROBLÈME AVEC EAGER ===
// Si on a 100 auteurs
List<Author> authors = authorRepo.findAll();
// SQL : 1 requête pour les auteurs
// + 100 requêtes pour les livres de chaque auteur (N+1 problem) !
Validation - Annotations
Annotation
Description
Code Exemple
@Valid
Déclenche la validation de l'objet
@PostMapping
public User create(@Valid @RequestBody User user) { ... }
@NotNull
Valeur non null (mais vide autorisé)
@NotNull private String name;
@NotEmpty
Non null ET non vide (String, Collection)
@NotEmpty private List<String> items;
@NotBlank
String non null, non vide, non espaces uniquement
@NotBlank private String email;
@Size
Taille min/max (String, Collection)
@Size(min=2, max=50) private String name;
@Min / @Max
Valeurs numériques min/max
@Min(0) @Max(100) private int age;
@Email
Format email valide
@Email private String email;
@Pattern
Regex personnalisée
@Pattern(regexp="[A-Z]{2}") private String code;
Exemple complet - Validation DTO :
public class UserDTO {
@NotBlank(message = "Le nom est obligatoire")
@Size(min = 2, max = 50, message = "Le nom doit contenir entre 2 et 50 caractères")
private String name;
@Email(message = "Email invalide")
@NotBlank
private String email;
@Min(value = 18, message = "Vous devez avoir au moins 18 ans")
private int age;
}
// Controller
@PostMapping("/users")
public ResponseEntity<?> createUser(@Valid @RequestBody UserDTO userDTO, BindingResult result) {
if (result.hasErrors()) {
// Retourner les erreurs
return ResponseEntity.badRequest().body(result.getAllErrors());
}
return ResponseEntity.ok(userService.create(userDTO));
}
// Test avec JSON invalide :
// { "name": "", "email": "bad-email", "age": 10 }
// Résultat (400 Bad Request) :
// [
// {"field": "name", "message": "Le nom est obligatoire"},
// {"field": "email", "message": "Email invalide"},
// {"field": "age", "message": "Vous devez avoir au moins 18 ans"}
// ]
Gestion des Exceptions
Annotation
Rôle
Code Exemple
@ControllerAdvice
Classe globale pour gérer les exceptions de tous les controllers
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleNotFound(UserNotFoundException ex) {
return ResponseEntity.status(404).body(ex.getMessage());
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGeneric(Exception ex) {
return ResponseEntity.status(500).body("Erreur interne");
}
}
@ExceptionHandler
Méthode gérant une exception spécifique
// Dans @ControllerAdvice ou Controller
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<String> handleIllegal(IllegalArgumentException ex) {
return ResponseEntity.badRequest().body(ex.getMessage());
}
Exemple complet - Gestion globale des erreurs :
// 1. Exception personnalisée
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
// 2. Gestionnaire global
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<Map<String, String>> handleNotFound(ResourceNotFoundException ex) {
Map<String, String> error = new HashMap<>();
error.put("error", "Not Found");
error.put("message", ex.getMessage());
error.put("timestamp", LocalDateTime.now().toString());
return ResponseEntity.status(404).body(error);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidation(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage())
);
return ResponseEntity.badRequest().body(errors);
}
}
// 3. Utilisation dans le Service
public User getUserById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + id));
}
// Résultat si user introuvable :
// HTTP 404
// {
// "error": "Not Found",
// "message": "User not found with id: 999",
// "timestamp": "2024-03-13T10:30:00"
// }
Configuration - application.properties
Propriété
Description
Exemple
server.port
Port du serveur embarqué
server.port=8081
spring.application.name
Nom de l'application
spring.application.name=mon-app
spring.datasource.url
URL de connexion BDD
spring.datasource.url=jdbc:mysql://localhost:3306/db
spring.datasource.username
Utilisateur BDD
spring.datasource.username=root
spring.datasource.password
Mot de passe BDD
spring.datasource.password=secret
spring.jpa.hibernate.ddl-auto
Stratégie génération schéma
spring.jpa.hibernate.ddl-auto=update (create, none)
@Value
Injecter valeur propriété
@Value("${server.port}")
private String port;
Exemple - Fichier application.properties complet :
# ===== SERVER =====
server.port=8080
# ===== DATABASE =====
spring.datasource.url=jdbc:mysql://localhost:3306/ma_base
spring.datasource.username=root
spring.datasource.password=secret
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# ===== JPA / HIBERNATE =====
# Affiche les requêtes SQL dans la console
spring.jpa.show-sql=true
# Formate le SQL
spring.jpa.properties.hibernate.format_sql=true
# Met à jour le schéma automatiquement (ATTENTION en prod !)
spring.jpa.hibernate.ddl-auto=update
# ===== LOGGING =====
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=trace
# ===== CUSTOM =====
app.jwt.secret=monSecretTresLong
app.pagination.default-size=20
JpaRepository - Méthodes par défaut
Méthode
Description
Exemple
save()
Créer ou mettre à jour une entité
User saved = userRepo.save(user);
findById()
Trouver par ID (retourne Optional)
Optional<User> user = userRepo.findById(1L);
findAll()
Récupérer toutes les entités
List<User> users = userRepo.findAll();
deleteById()
Supprimer par ID
userRepo.deleteById(1L);
count()
Compter les entités
long total = userRepo.count();
existsById()
Vérifier existence par ID
boolean exists = userRepo.existsById(1L);
Exemple - Requêtes dérivées (Derived Queries) :
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Spring génère le SQL automatiquement selon le nom de la méthode !
// SELECT * FROM users WHERE email = ?
Optional<User> findByEmail(String email);
// SELECT * FROM users WHERE name = ? AND active = true
List<User> findByNameAndActiveTrue(String name);
// SELECT * FROM users WHERE age > ? ORDER BY name ASC
List<User> findByAgeGreaterThanOrderByAgeAsc(int age);
// SELECT * FROM users WHERE name LIKE %?%
List<User> findByNameContaining(String keyword);
// SELECT COUNT(*) FROM users WHERE active = true
long countByActiveTrue();
// DELETE FROM users WHERE active = false
void deleteByActiveFalse();
// @Query personnalisée (JPQL)
@Query("SELECT u FROM User u WHERE u.email LIKE %:domain")
List<User> findByEmailDomain(@Param("domain") String domain);
// Requête native SQL
@Query(value = "SELECT * FROM users u WHERE u.role = :role", nativeQuery = true)
List<User> findByRoleNative(@Param("role") String role);
}
// Utilisation :
List<User> admins = userRepo.findByRoleNative("admin");
FetchType :
LAZY : chargement différé (optimisation mémoire) - données chargées uniquement quand accédées
EAGER : chargement immédiat (consommateur de ressources) - données chargées avec l'entité parent
🚀 Laravel
Définition : Framework PHP MVC basé sur Symfony offrant syntaxe élégante et outils intégrés. Eloquent ORM Active Record, Blade templating, Artisan CLI.
Commandes Artisan Essentielles
Commande
Action
Exemple / Options
php artisan serve
Lancer serveur dev (port 8000)
php artisan serve --port=8080
php artisan make:controller
Générer contrôleur
php artisan make:controller UserController --resource (7 méthodes REST)
php artisan make:model
Créer modèle Eloquent
php artisan make:model User -mfsc (Model + Migration + Factory + Seeder + Controller)
php artisan migrate
Exécuter migrations
php artisan migrate --force (production)
php artisan migrate:fresh --seed
Réinitialiser BDD + seeders
php artisan migrate:fresh --seed (DROP ALL + recrée + données test)
php artisan db:seed
Exécuter seeders
php artisan db:seed --class=UserSeeder
php artisan tinker
Console interactive REPL
User::find(1) ou $user = new User(['name' => 'John'])
php artisan route:list
Afficher toutes les routes
php artisan route:list --path=api
php artisan cache:clear
Vider cache application
php artisan config:cache (cache config production)
Exemple - Workflow complet de création :
# 1. Créer un Model avec Migration et Controller Resource
php artisan make:model Product -mr
# Résultat fichiers créés :
# app/Models/Product.php
# database/migrations/2024_03_13_create_products_table.php
# app/Http/Controllers/ProductController.php
# 2. Modifier la migration (database/migrations/...)
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->decimal('price', 8, 2);
$table->timestamps();
});
# 3. Exécuter la migration
php artisan migrate
# Résultat : Table 'products' créée en BDD
Eloquent ORM - Méthodes Clés
Méthode
Action
Retourne si non trouvé
Code Exemple
all()
Tous les enregistrements
Collection vide
$users = User::all();
find($id)
Recherche par ID
null
$user = User::find(1);
findOrFail($id)
Recherche par ID
Exception 404
$user = User::findOrFail(1); // Auto 404 si inexistant
first()
Premier résultat
null
$user = User::where('active', 1)->first();
firstOrFail()
Premier résultat
Exception 404
$user = User::where('email', $email)->firstOrFail();
firstOrCreate($attrs)
Recherche ou crée
Instance (existante ou nouvelle)
User::firstOrCreate(['email' => 'test@test.com'], ['name' => 'John']);
create($data)
Créer (respecte $fillable)
Instance créée
$user = User::create(['name' => 'John', 'email' => 'john@test.com']);
update($data)
Met à jour l'instance
bool
$user->update(['name' => 'Jane']);
save()
Persiste l'instance
bool
$user->name = 'Jane'; $user->save();
delete()
Supprime l'instance
bool
$user->delete();
destroy($id)
Supprime par ID
int (nb supprimés)
User::destroy(1); ou User::destroy([1, 2, 3]);
where($col, $op, $val)
Condition WHERE
Query Builder
User::where('age', '>', 18)->get();
paginate($n)
Pagination
LengthAwarePaginator
$users = User::paginate(10); // 10 par page
with($relation)
Eager loading (évite N+1)
Query Builder
$users = User::with('posts')->get();
Exemple complet - CRUD avec Eloquent :
// ===== CREATE =====
// Méthode 1: Instanciation + save()
$user = new User();
$user->name = 'Alice';
$user->email = 'alice@test.com';
$user->save(); // INSERT INTO users...
// Méthode 2: Mass Assignment (rapide)
$user = User::create([
'name' => 'Bob',
'email' => 'bob@test.com'
]); // Respecte $fillable dans le modèle
// ===== READ =====
// Récupérer tous
$allUsers = User::all(); // Collection
// Récupérer par ID
$user = User::find(1); // Retourne User ou null
// Récupérer avec conditions
$activeUsers = User::where('active', true)
->orderBy('name')
->get(); // Collection
// ===== UPDATE =====
$user = User::find(1);
$user->email = 'new-email@test.com';
$user->save(); // UPDATE users SET email = ...
// Mass update
User::where('active', false)->update(['status' => 'archived']);
// ===== DELETE =====
$user = User::find(1);
$user->delete(); // DELETE FROM users WHERE id = 1
// Delete par ID
User::destroy(2); // Supprime user ID 2
User::destroy([3, 4]); // Supprime users ID 3 et 4
Différences clés :
find() = retourne null si inexistant | findOrFail() = lance exception 404 si inexistant
create() = Eloquent avec événements (respecte $fillable) | insert() = SQL brut rapide (pas d'événements)
save() = sur instance existante | update() = mass update sur query builder
Relations Eloquent
Méthode
Relation
Code Exemple
hasOne()
Un-à-un (détient FK)
// User a un Profile
public function profile() {
return $this->hasOne(Profile::class);
}
belongsTo()
Inverse one-to-one/many-to-one
// Profile appartient à User
public function user() {
return $this->belongsTo(User::class);
}
hasMany()
Un-à-plusieurs
// User a plusieurs Posts
public function posts() {
return $this->hasMany(Post::class);
}
belongsToMany()
Plusieurs-à-plusieurs (table pivot)
// User a plusieurs Roles (table pivot role_user)
public function roles() {
return $this->belongsToMany(Role::class);
}
Exemple - Relation OneToMany et utilisation :
// ===== Modèles =====
// app/Models/User.php
class User extends Model {
public function posts() {
return $this->hasMany(Post::class);
// Laravel suppose que la table 'posts' a une colonne 'user_id'
}
}
// app/Models/Post.php
class Post extends Model {
public function user() {
return $this->belongsTo(User::class);
}
}
// ===== Utilisation dans Controller =====
// 1. Récupérer les posts d'un utilisateur
$user = User::find(1);
$posts = $user->posts; // Collection de posts
// 2. Récupérer l'auteur d'un post
$post = Post::find(1);
$author = $post->user; // Instance de User
// 3. Créer un post pour un user
$user->posts()->create([
'title' => 'Mon premier article',
'content' => 'Contenu...'
]); // user_id est automatiquement défini
// 4. Eager Loading (optimisation N+1)
// Sans with() : 1 requête users + N requêtes posts
// Avec with() : 2 requêtes seulement
$users = User::with('posts')->get();
foreach ($users as $user) {
echo $user->posts->count(); // Pas de requête supplémentaire
}
Sécurité - Mass Assignment
Propriété
Rôle
Code Exemple
$fillable
Whitelist : champs autorisés pour create/update
protected $fillable = ['name', 'email', 'password'];
// Seuls ces champs peuvent être assignés en masse
$guarded
Blacklist : champs interdits (inverse de fillable)
protected $guarded = ['is_admin', 'role'];
// Tous les champs SAUF ceux-ci sont assignables
Exemple - Protection Mass Assignment :
// Modèle User
class User extends Model {
// Sécurité : seul 'name' et 'email' sont assignables via create()
protected $fillable = ['name', 'email'];
}
// Tentative d'attaque (Injection de rôle admin)
User::create([
'name' => 'Hacker',
'email' => 'hack@test.com',
'role' => 'admin' // ⚠️ IGNORÉ car pas dans $fillable
]);
// Résultat en base :
// { id: 2, name: "Hacker", email: "hack@test.com", role: "user" }
// Le champ 'role' n'a pas été modifié.
// Alternative : Tout autoriser (déconseillé en prod)
// protected $guarded = []; // Vide = tout est fillable
Routing
Méthode
Usage
Code Exemple
Route::get()
Route GET
Route::get('/users', [UserController::class, 'index']);
Route::post()
Route POST
Route::post('/users', [UserController::class, 'store']);
Route::put()
Route PUT
Route::put('/users/{id}', [UserController::class, 'update']);
Route::delete()
Route DELETE
Route::delete('/users/{id}', [UserController::class, 'destroy']);
Route::resource()
7 routes REST complètes
Route::resource('users', UserController::class); // index, create, store, show, edit, update, destroy
Route::apiResource()
5 routes API (sans create/edit)
Route::apiResource('users', UserController::class); // index, store, show, update, destroy
->name()
Nommer une route
Route::get('/users', [UserController::class, 'index'])->name('users.index');
->middleware()
Appliquer middleware
Route::get('/admin', [AdminController::class, 'index'])->middleware('auth');
Exemple - Routes API Resource :
// routes/web.php ou routes/api.php
use App\Http\Controllers\ProductController;
// Une seule ligne pour 5 routes REST
Route::apiResource('products', ProductController::class);
// Equivalent à écrire manuellement :
// Method URI Action
// GET /products index
// POST /products store
// GET /products/{product} show
// PUT/PATCH /products/{product} update
// DELETE /products/{product} destroy
// ===== ProductController.php (Généré avec --api) =====
class ProductController extends Controller {
public function index() {
return Product::all();
}
public function store(Request $request) {
return Product::create($request->all());
}
public function show(Product $product) {
return $product; // Route Model Binding
}
public function update(Request $request, Product $product) {
$product->update($request->all());
return $product;
}
public function destroy(Product $product) {
$product->delete();
return response()->json(null, 204);
}
}
Blade Directives
Directive
Usage
Code Exemple
@extends('layout')
Hérite d'un template
@extends('layouts.app')
@section('nom')
Définit une section
@section('content') ... @endsection
@yield('nom')
Emplacement d'injection
<main>@yield('content')</main> (dans layout)
@include('vue')
Inclut une sous-vue
@include('partials.header')
@if
Condition
@if($user->isAdmin())
<p>Admin</p>
@elseif($user->isEditor())
<p>Editor</p>
@else
<p>User</p>
@endif
@foreach
Boucle sur collection
@foreach($users as $user)
<p>{{ $user->name }}</p>
@endforeach
@forelse
Boucle avec gestion cas vide
@forelse($users as $user)
<p>{{ $user->name }}</p>
@empty
<p>Aucun utilisateur</p>
@endforelse
@csrf
Token protection CSRF
<form>@csrf ...</form> // OBLIGATOIRE pour POST/PUT/DELETE
@method('PUT')
Spoofing méthode HTTP
<form>@csrf @method('PUT') ...</form> // Pour simuler PUT dans form HTML
@auth / @guest
Vérification authentification
@auth
Bienvenue {{ Auth::user()->name }}
@guest
<a href="/login">Connexion</a>
@endauth
Exemple - Layout et Page Blade :
// ===== resources/views/layouts/app.blade.php =====
Mon Site - @yield('title')
@include('partials.navbar') // Inclusion
@yield('content') // Emplacement principal
@stack('scripts') // Pile de scripts
// ===== resources/views/users/index.blade.php =====
@extends('layouts.app') // Héritage
@section('title', 'Liste des utilisateurs')
@section('content')
<h1>Utilisateurs</h1>
@forelse($users as $user)
<div class="card">
<h3>{{ $user->name }}</h3>
<p>{{ $user->email }}</p>
</div>
@empty
<p>Aucun utilisateur trouvé.</p>
@endforelse
@push('scripts')
<script src="/js/users.js"></script>
@endpush
@endsection
Validation - Règles Courantes
Règle
Description
Exemple
required
Champ obligatoire
'name' => 'required'
nullable
Peut être null
'bio' => 'nullable|string'
string
Doit être une chaîne
'name' => 'required|string|max:255'
email
Format email valide
'email' => 'required|email|unique:users'
unique:table,column
Valeur unique en BDD
'email' => 'unique:users,email'
exists:table,column
Doit exister en BDD
'user_id' => 'exists:users,id'
min:value
Taille minimale
'password' => 'min:8'
confirmed
Doit avoir champ _confirmation
'password' => 'required|confirmed' // attend password_confirmation
array
Doit être un tableau
'tags' => 'array'
Exemple - Validation dans Controller :
// UserController.php
public function store(Request $request) {
// Validation automatique
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:8|confirmed',
]);
// Si validation échoue : redirection automatique avec erreurs
// Si succès : on continue
$user = User::create($validated);
return redirect()->route('users.show', $user);
}
// ===== Affichage des erreurs dans Blade =====
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
// Exemple si email invalide envoyé :
// Erreur : "The email must be a valid email address."
Middleware
Concept
Description
Code Exemple
handle()
Méthode principale du middleware
public function handle($request, $next) {
if (!Auth::check()) {
return redirect('login');
}
return $next($request); // Passe au suivant
}
Route::middleware()
Appliquer à une route
Route::get('/admin', fn() => view('admin'))->middleware('auth');
Middleware Groups
Groupes prédéfinis
web (sessions, CSRF) et api (stateless, throttle)
Exemple - Middleware personnalisé :
# 1. Création
php artisan make:middleware CheckAdmin
// app/Http/Middleware/CheckAdmin.php
public function handle($request, Closure $next) {
if (auth()->user()->role !== 'admin') {
abort(403, 'Accès non autorisé');
}
return $next($request);
}
// 2. Enregistrement dans app/Http/Kernel.php
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\CheckAdmin::class,
];
// 3. Utilisation dans routes/web.php
Route::get('/admin/dashboard', function () {
return "Dashboard Admin";
})->middleware(['auth', 'admin']); // Empilé : il faut être connecté ET admin
// Résultat si user non-admin essaie d'accéder :
// HTTP 403 Forbidden
Configuration & Environnement
Fichier/Fonction
Usage
Exemple
.env
Variables d'environnement
APP_NAME=Laravel
DB_DATABASE=laravel_db
env('KEY', $default)
Lire variable env
$db = env('DB_DATABASE', 'forge');
config('file.key')
Lire configuration
$timezone = config('app.timezone');
Helpers Essentiels
Helper
Description
Exemple
route('name')
Génère URL depuis nom de route
<a href="{{ route('users.index') }}">Users</a>
url('path')
Génère URL absolue
url('/images/logo.png')
asset('path')
URL vers fichier public
<img src="{{ asset('images/logo.png') }}">
storage_path('path')
Chemin vers storage
storage_path('app/public/file.txt')
Hash::make()
Hacher mot de passe (Bcrypt)
$user->password = Hash::make('secret');
Auth::user()
Utilisateur connecté
{{ Auth::user()->name }}
Exemple - Fichier .env et utilisation :
// .env (à la racine)
APP_NAME="Mon Projet"
APP_ENV=local
APP_DEBUG=true
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ma_base
DB_USERNAME=root
DB_PASSWORD=secret
// Utilisation dans config/database.php
'mysql' => [
'database' => env('DB_DATABASE', 'forge'),
// Si .env absent, utilise 'forge' par défaut
],
// Accès dans le code
$appName = env('APP_NAME'); // "Mon Projet"
$debug = config('app.debug'); // true
// ⚠️ Ne jamais commiter le fichier .env sur Git !
// Utiliser .env.example comme template
⚠️ Points clés pour QCM :
1. find() vs findOrFail() : null vs Exception 404
2. $fillable (whitelist) vs $guarded (blacklist) pour Mass Assignment
3. Route::resource() = 7 routes (avec vues) vs Route::apiResource() = 5 routes (API uniquement)
4. hasMany() = côté "un" de la relation | belongsTo() = côté "plusieurs" (détient FK)
5. @csrf OBLIGATOIRE dans tous les formulaires POST/PUT/DELETE
6. with() = eager loading (évite requêtes N+1)
🌐 Réseaux
Modèle OSI (7 couches)
Couche
Nom
Fonction
Exemples
7
Application
Services réseau pour applications
HTTP, FTP, SMTP, DNS
6
Présentation
Encodage, compression, chiffrement
SSL/TLS, JPEG, ASCII
5
Session
Gestion des dialogues
NetBIOS, RPC
4
Transport
Fiabilité, séquencement, ports
TCP, UDP
3
Réseau
Routage, adressage logique (IP)
IP, ICMP, OSPF
2
Liaison
Adressage physique (MAC), switch
Ethernet, PPP
1
Physique
Signaux, câbles, bits
Câble RJ45, fibre, Hub
Protocoles Essentiels
Protocole
Port
Fonction
HTTP / HTTPS
80 / 443
Web (chiffrement SSL/TLS pour HTTPS)
FTP / SFTP
21 / 22
Transfert fichiers (SFTP sécurisé)
SMTP / POP3 / IMAP
25 / 110 / 143
Email (envoi / réception)
DNS
53
Résolution noms de domaine → IP
DHCP
67/68
Attribution dynamique d'IP
SSH
22
Connexion sécurisée distante
TCP vs UDP
TCP (6)
UDP (17)
Connexion fiable
Non fiable
Séquencement garanti
Pas de séquencement
Accusé de réception (ACK)
Pas d'ACK
Lent (overhead)
Rapide (streaming)
Matériel Réseau
Matériel
Couche OSI
Fonction
Hub
1 (Physique)
Broadcast tout (ancien, non intelligent)
Switch
2 (Liaison)
Commutation par MAC (intelligent)
Routeur
3 (Réseau)
Routage par IP entre réseaux
Firewall
3-7
Sécurité, filtrage paquets
Commandes Réseau
Commande
Usage
ping
Tester connectivité
ipconfig / ifconfig
Configuration IP locale
tracert / traceroute
Chemin vers destination
nslookup / dig
Résolution DNS
netstat
Connexions actives et ports
arp -a
Table ARP (IP ↔ MAC)
Adresses IP privées :
Classe A : 10.0.0.0 - 10.255.255.255
Classe B : 172.16.0.0 - 172.31.255.255
Classe C : 192.168.0.0 - 192.168.255.255
📦 Git & GitHub
Mots clés : VCS (Version Control System), Décentralisé, Historique
Git est un système de contrôle de version distribué. Il permet de suivre les modifications, revenir en arrière et collaborer.
Les 3 Zones Git
Zone
Nom
Description
1. Working Directory
Répertoire de travail
Fichiers modifiés mais pas encore indexés
2. Staging Area (Index)
Zone de préparation
Fichiers prêts à être commités (git add)
3. Repository (.git)
Dépôt local
Historique complet des commits (git commit)
Commandes Essentielles
Commande
Action
Exemple
git init
Initialiser un dépôt
Crée le dossier caché .git
git clone url
Copier un dépôt distant
git clone https://github.com/user/repo.git
git status
Voir l'état des fichiers
Rouge = non suivi, Vert = stagé
git add fichier
Ajouter au Staging
git add . (ajoute tout)
git commit -m "msg"
Sauvegarder dans l'historique
Crée un "snapshot" immuable
git push
Envoyer vers le distant
git push origin main
git pull
Récupérer et fusionner
git pull origin main
git log
Voir l'historique
git log --oneline (compact)
Gestion des Branches
Mots clés : Branch, Head, Merge, Checkout
Une branche est un pointeur mobile vers un commit.
git branch feature-login // Créer branche
git checkout feature-login // Basculer dessus
git checkout -b feature-x // Créer + Basculer (raccourci)
// Après travail sur la branche
git checkout main // Retour au tronc
git merge feature-login // Fusionner dans main
Fichier .gitignore
Usage : Ignorer des fichiers (ne jamais les tracker).
# Contenu typique de .gitignore
node_modules/ # Dossiers dépendances
.env # Fichiers secrets
*.log # Tous les fichiers .log
build/ # Dossiers de build
🐳 Docker & DevOps
Définition : Docker est une plateforme de conteneurisation. Elle permet d'empaqueter une application avec toutes ses dépendances dans un "Conteneur" isolé, assurant ainsi qu'elle fonctionne de manière identique partout.
Concepts Clés
Concept
Analogie
Description
Image
Recette de cuisine / Classe
Modèle en lecture seule (Bluepring). Contient l'OS, libs, code.
Conteneur
Plat cuisiné / Objet
Instance en cours d'exécution d'une image. Isolé, léger.
Dockerfile
Mode d'emploi
Fichier texte contenant les instructions pour construire une image.
Volume
Disque dur externe
Stockage persistant. Les données survivent à la suppression du conteneur.
Commandes Docker
Commande
Action
docker build -t nom .
Construire une image depuis Dockerfile
docker run -d -p 80:80 nom
Lancer un conteneur (-d: détaché, -p: port)
docker ps
Lister les conteneurs actifs
docker stop id
Arrêter un conteneur
docker exec -it id bash
Entrer dans le conteneur (shell interactif)
Dockerfile - Instructions
Exemple de Dockerfile standard :
FROM node:18-alpine # Image de base
WORKDIR /app # Dossier de travail
COPY package*.json ./ # Copier fichiers dépendances
RUN npm install # Installer dépendances
COPY . . # Copier tout le code
EXPOSE 3000 # Exposer le port
CMD ["npm", "start"] # Commande au démarrage
Docker Compose
Mots clés : Multi-conteneurs, Orchestration local
Outil pour définir et lancer des applications multi-conteneurs via un fichier YAML.
# docker-compose.yml
version: '3'
services:
web:
image: nginx
ports:
- "8080:80"
database:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: secret
# Commande : docker-compose up -d
🧮 Algorithmes & Complexité
Objectif : Résoudre des problèmes de manière efficace. On mesure l'efficacité par la complexité temporelle (temps d'exécution) et spatiale (mémoire utilisée).
Notation Big O (Complexité)
Notation
Nom
Performance
Exemple
O(1)
Constant
⭐⭐⭐ Excellent
Accès à un élément d'un tableau par index arr[5]
O(log n)
Logarithmique
⭐⭐ Bon
Recherche binaire (Binary Search)
O(n)
Linéaire
⭐ Moyen
Parcourir une liste simple
O(n log n)
Linéarithmique
⭐ Acceptable
Tri rapide (Quick Sort), Tri fusion (Merge Sort)
O(n²)
Quadratique
❌ Mauvais
Boucles imbriquées, Tri à bulles
Règle d'or : On considère toujours le pire cas (Worst Case). Si un algorithme est rapide parfois mais lent sur de grandes données, on note sa complexité maximale.
Structures de Données
Structure
Description
Complexité Accès
Array (Tableau)
Collection indexée, taille fixe
O(1)
Linked List (Liste Chaînée)
Éléments liés par pointeurs
O(n)
Stack (Pile)
LIFO (Last In First Out)
Push/Pop: O(1)
Queue (File)
FIFO (First In First Out)
Enqueue/Dequeue: O(1)
Hash Table
Paires clé-valeur (Objet/Map)
Accès moyen: O(1)
Algorithmes de Tri
Algorithme
Complexité Moyenne
Principe
Bubble Sort
O(n²)
Compare et échange les éléments adjacents. Lent.
Quick Sort
O(n log n)
Choisit un pivot, divise le tableau, trie récursivement.
Merge Sort
O(n log n)
Divise pour régner. Fusionne des sous-tableaux triés.
Recherche
1. Recherche Linéaire (Linear Search) : O(n)
Parcourt chaque élément un par un.
for (let i = 0; i < arr.length; i++) {
if (arr[i] === target) return i;
}
2. Recherche Binaire (Binary Search) : O(log n)
Divise l'espace de recherche par 2 à chaque itération. Prérequis : Tableau trié.
let start = 0, end = arr.length - 1;
while (start <= end) {
let mid = Math.floor((start + end) / 2);
if (arr[mid] === target) return mid;
else if (arr[mid] < target) start = mid + 1;
else end = mid - 1;
}
📝 QCM DE RÉVISION GLOBALE
Chaque section contient 20 questions couvrant les notions essentielles du cours.
1. HTML & CSS
1. Quelle balise est utilisée pour définir l'importance sémantique (forte) d'un texte ?
Réponse : B (<strong> a une valeur sémantique, contrairement à <b>)
2. Quelle est la différence principale entre une classe (.class) et un ID (#id) ?
Réponse : C
3. Quelle propriété CSS permet de centrer un élément flex horizontalement et verticalement ?
Réponse : C
4. Dans le Box Model standard (content-box), la propriété width inclut :
Réponse : B
5. Quel attribut HTML est obligatoire pour les images pour l'accessibilité ?
Réponse : C
6. Quelle balise HTML5 est utilisée pour le contenu principal unique d'une page ?
Réponse : C
7. Comment inclure un fichier CSS externe ?
Réponse : B
8. Quelle est la spécificité CSS la plus élevée ?
Réponse : D (Inline style)
9. Quelle propriété retire l'élément du flux normal sans réserver d'espace ?
Réponse : A
10. Quelle unité est relative à la taille de la racine (<html>) ?
Réponse : C
11. Quelle balise est utilisée pour une navigation principale ?
Réponse : B
12. Comment sélectionner tous les éléments <p> directs à l'intérieur d'un <div> ?
Réponse : B
13. Quelle balise crée une liste numérotée ?
Réponse : C
14. Quelle est la valeur par défaut de la propriété position ?
Réponse : C
15. Quelle balise est utilisée pour créer un champ de saisie dans un formulaire ?
Réponse : A
16. Quelle propriété Flexbox définit l'axe principal ?
Réponse : B
17. Quel attribut de formulaire lie un label à un champ input ?
Réponse : C (l'input doit avoir l'id correspondant)
18. Quelle valeur de display transforme un élément en conteneur Grid ?
Réponse : C
19. Quel attribut empêche un champ de formulaire d'être vide ?
Réponse : B
20. Quel meta tag est indispensable pour le Responsive Design ?
Réponse : C
2. JavaScript
1. Quelle est la différence entre == et === ?
Réponse : B
2. Quelle méthode de tableau NE MODIFIE PAS l'original ?
Réponse : C
3. Quel est le résultat de typeof null ?
Réponse : C (Bug historique JS)
4. Comment déclarer une variable non réassignable ?
Réponse : C
5. Quelle méthode DOM retourne le premier élément correspondant à un sélecteur CSS ?
Réponse : C
6. Quelle méthode transforme un tableau en appliquant une fonction à chaque élément ?
Réponse : C
7. Quelle est la sortie de [1, 2, 3].pop() ?
Réponse : B (pop retourne l'élément supprimé)
8. Comment convertir une chaîne JSON en objet JS ?
Réponse : B
9. Quelle est la portée de var ?
Réponse : B
10. Quelle propriété compte le nombre de caractères d'une chaîne ?
Réponse : B
11. "Hello".indexOf("z") retourne ?
Réponse : C
12. Quelle méthode supprime le premier élément d'un tableau ?
Réponse : A
13. Quelle syntaxe est correcte pour une arrow function ?
Réponse : B
14. Que retourne document.getElementsByClassName("x") ?
Réponse : C
15. Comment ajouter un événement clic ?
Réponse : D (Mais addEventListener est recommandé)
16. Quelle méthode fusionne des tableaux ?
Réponse : B
17. Quelle est la différence entre innerHTML et textContent ?
Réponse : B
18. Quel opérateur permet d'assigner une valeur par défaut si la variable est null/undefined ?
Réponse : C (Nullish coalescing)
19. Que signifie AJAX ?
Réponse : A
20. "5" + 3 donne ?
Réponse : B (Concaténation)
3. SQL, NoSQL, UML & OOP
1. Quelle commande SQL supprime complètement une table et ses données ?
Réponse : B
2. Quelle jointure retourne toutes les lignes de la table de gauche même sans correspondance ?
Réponse : C
3. Quelle est la différence entre WHERE et HAVING ?
Réponse : B
4. Quel type de NoSQL utilise des documents JSON/BSON ?
Réponse : C
5. En UML, quelle relation indique un cycle de vie dépendant (la partie meurt avec le tout) ?
Réponse : C
6. En OOP, quel concept cache l'état interne d'un objet ?
Réponse : C
7. Quel concept permet à une classe d'hériter des propriétés d'une autre ?
Réponse : B
8. Quelle requête SQL efface toutes les lignes d'une table sans journalisation (rapide) ?
Réponse : C
9. En UML, <> signifie :
Réponse : B
10. Quelle fonction SQL compte le nombre de lignes ?
Réponse : B
11. SQL est aux bases relationnelles ce que NoSQL est aux :
Réponse : C
12. Une interface en OOP est :
Réponse : B
13. Le polymorphisme permet :
Réponse : B
14. Quelle est la bonne syntaxe pour un tri décroissant ?
Réponse : A
15. Quel symbole représente l'agrégation en UML ?
Réponse : B
16. La clé primaire (PRIMARY KEY) :
Réponse : B
17. En NoSQL, le scaling horizontal signifie :
Réponse : B
18. Quel diagramme UML montre l'ordre des messages entre objets ?
Réponse : C
19. Une classe abstraite :
Réponse : B
20. Quel mot-clé SQL filtre un groupe après GROUP BY ?
Réponse : C
4. Langages (C, Java, Python, PHP)
1. En C, pourquoi utilise-t-on & dans scanf("%d", &x) ?
Réponse : B
2. En Java, comment compare-t-on le contenu de deux String ?
Réponse : B
3. En Python, quelle structure est IMMUTABLE (non modifiable) ?
Réponse : C
4. En PHP, quelle fonction ajoute un élément à la fin d'un tableau ?
Réponse : A
5. Quel est le point d'entrée d'un programme C ?
Réponse : C
6. En Java, quelle méthode affiche une ligne dans la console ?
Réponse : B
7. En Python, comment insérer un élément à un index spécifique ?
Réponse : B
8. En PHP, comment déclare-t-on une variable ?
Réponse : B
9. En C, %d est le format pour :
Réponse : C
10. En Java, int est un type primitif, Integer est :
Réponse : B
11. En Python, "Hello".upper() retourne :
Réponse : B
12. En PHP, quelle fonction compte les éléments d'un tableau ?
Réponse : B
13. En C, strlen() retourne :
Réponse : B
14. En Java, ArrayList stocke :
Réponse : B (Les types primitifs utilisent les wrappers comme Integer)
15. En Python, quelle fonction lit l'entrée utilisateur ?
Réponse : C
16. En PHP, quelle instruction affiche du texte ?
Réponse : D
17. En C, la fonction strcpy sert à :
Réponse : B
18. En Java, String est :
Réponse : B
19. En Python, range(5) génère :
Réponse : B
20. En PHP, strpos() retourne :
Réponse : A
5. React.js
1. React est une :
Réponse : B
2. Quel hook gère l'état local ?
Réponse : B
3. Les Props sont :
Réponse : B
4. Qu'est-ce que le Virtual DOM ?
Réponse : B
5. Quelle règle est vraie pour JSX ?
Réponse : B
6. Comment optimiser les listes en React ?
Réponse : B
7. useEffect(() => {}, []) s'exécute :
Réponse : B
8. Comment accéder directement à un élément DOM ?
Réponse : B
9. Comment déclencher une mise à jour du state ?
Réponse : B
10. Que retourne map() en JSX ?
Réponse : B
11. "Lifting State Up" signifie :
Réponse : B
12. Quelle syntaxe pour un événement clic ?
Réponse : B
13. React.memo est utilisé pour :
Réponse : B
14. useState est :
Réponse : B
15. Comment passer des données entre composants non liés ?
Réponse : B
16. Quel hook remplace componentDidMount, componentDidUpdate ?
Réponse : B
17. className en JSX remplace :
Réponse : B
18. Un composant contrôlé (controlled component) signifie :
Réponse : B
19. Où place-t-on les effets de bord (API calls) ?
Réponse : B
20. React est :
Réponse : B
6. Angular
1. Angular utilise principalement quel langage ?
Réponse : B
2. Quelle syntaxe pour le Two-Way Binding ?
Réponse : C ("Banana in a box")
3. Quel décorateur crée un composant ?
Réponse : B
4. Quelle commande CLI crée un nouveau projet ?
Réponse : A
5. *ngIf est une directive :
Réponse : B
6. Le décorateur @Input() permet :
Réponse : A
7. Quel hook est appelé à l'initialisation du composant ?
Réponse : B
8. providedIn: 'root' dans un service signifie :
Réponse : B
9. Quelle syntaxe pour la liaison d'événement ?
Réponse : B
10. HttpClient retourne un :
Réponse : B
11. Quelle balise HTML utilise-t-on pour le routing ?
Réponse : A
12. La wildcard route est définie par :
Réponse : B
13. *ngFor="let item of items" itère sur :
Réponse : B
14. NgModule regroupe :
Réponse : A
15. Pourquoi utiliser trackBy avec ngFor ?
Réponse : B
16. La liaison par interpolation utilise :
Réponse : C
17. AngularJS (v1) vs Angular (v2+) : Angular utilise :
Réponse : B
18. Un Pipe transforme :
Réponse : B
19. ng serve lance :
Réponse : B
20. Pour utiliser ngModel, quel module est nécessaire ?
Réponse : B
7. Spring Boot
1. @SpringBootApplication combine :
Réponse : B
2. @RestController est équivalent à :
Réponse : A
3. @Autowired permet :
Réponse : B
4. Quelle annotation mappe une classe à une table BDD ?
Réponse : B
5. @Transactional assure :
Réponse : B
6. JpaRepository hérite de :
Réponse : A
7. @Id désigne :
Réponse : B
8. @ManyToOne est une relation :
Réponse : B
9. Quelle annotation mappe une requête HTTP GET ?
Réponse : C
10. @PathVariable extrait :
Réponse : B
11. FetchType.LAZY signifie :
Réponse : B
12. @Service est une spécialisation de :
Réponse : B
13. application.properties contient :
Réponse : B
14. @Valid déclenche :
Réponse : B
15. CascadeType.ALL propage :
Réponse : B
16. @JoinColumn est utilisé pour :
Réponse : B
17. @ControllerAdvice gère :
Réponse : B
18. Quelle est la méthode HTTP pour créer une ressource ?
Réponse : B
19. mvn spring-boot:run permet de :
Réponse : B
20. @OneToMany est l'inverse de :
Réponse : B
8. Laravel
1. La commande pour lancer le serveur local est :
Réponse : B
2. Eloquent est :
Réponse : B
3. @csrf dans un formulaire sert à :
Réponse : B
4. Quelle méthode Eloquent récupère tous les enregistrements ?
Réponse : B
5. Blade est :
Réponse : B
6. php artisan make:model -m crée :
Réponse : B
7. $fillable dans un modèle définit :
Réponse : B
8. Route::resource crée :
Réponse : B
9. La validation 'required' signifie :
Réponse : B
10. @extends('layout') permet :
Réponse : B
11. findOrFail($id) retourne :
Réponse : B
12. Les migrations permettent :
Réponse : B
13. hasMany définit une relation :
Réponse : B
14. php artisan migrate:fresh :
Réponse : B
15. @yield('content') sert à :
Réponse : B
16. belongsToMany définit :
Réponse : B
17. Le dossier des contrôleurs est :
Réponse : B
18. with('relation') permet :
Réponse : B
19. Middleware dans Laravel agit comme :
Réponse : B
20. Envoyer une requête POST en Laravel crée souvent une donnée, quelle méthode est utilisée dans le contrôleur ?
Réponse : B (store gère la logique POST)
9. Réseaux
1. Sur quelle couche OSI travaille un Switch classique ?
Réponse : B
2. Quel protocole est "non fiable" et rapide ?
Réponse : B
3. DNS traduit :
Réponse : B
4. DHCP attribue :
Réponse : B
5. Quelle est la couche du modèle OSI pour IP ?
Réponse : C
6. HTTP utilise par défaut le port :
Réponse : C
7. HTTPS sécurise via :
Réponse : B
8. Une adresse IPv4 fait :
Réponse : C
9. Le routeur connecte :
Réponse : B
10. ARP associe :
Réponse : A
11. TCP assure :
Réponse : B
12. Le port 443 correspond à :
Réponse : B
13. 192.168.1.1 est une adresse :
Réponse : B
14. VPN signifie :
Réponse : A
15. La commande ping utilise le protocole :
Réponse : C
16. SMTP est utilisé pour :
Réponse : B
17. Un Firewall sert à :
Réponse : B
18. FTP utilise le port :
Réponse : A
19. NAT permet :
Réponse : A
20. Le modèle TCP/IP simplifié a combien de couches ?
Réponse : B
📝 QCM Géant (400 Questions)
Aucun commentaire:
Enregistrer un commentaire