04

Structures Conditionnelles

Guide Complet : 10+ Patterns Modernes

🌗 Fondation : Truthy vs Falsy

En JS, 6 valeurs sont Falsy. Tout le reste est Truthy.

0️⃣
0
""
String vide
👻
null
undefined
🚫
false
🔢
NaN
📦
{}
📜
[]
📝
"0"

🏗️ Les 10 Structures Conditionnelles

1️⃣ If / Else (Classique)
if (age >= 18) {
    console.log("Majeur");
} else if (age >= 13) {
    console.log("Ado");
} else {
    console.log("Enfant");
}
Cas d'usage : Logique simple avec blocs de code.
2️⃣ Ternaire (? :)
const status = isOnline 
    ? "🟢 En ligne" 
    : "🔴 Hors ligne";

// ❌ Éviter imbrication
const x = a ? (b ? 1 : 2) : 3;
Cas d'usage : Assignation conditionnelle simple (1 ligne).
3️⃣ Short-Circuit (&&)
// Exécute si truthy
isLoggedIn && showDashboard();

// React pattern
{user && }
Cas d'usage : Exécution conditionnelle concise (React, Vue).
4️⃣ Fallback (||)
const name = userName || "Anonyme";

// ⚠️ Piège avec 0 et ""
const count = 0;
const val = count || 10; // 10 (Bug!)
Cas d'usage : Valeur par défaut (attention aux 0/false).
5️⃣ Nullish Coalescing (??)
const speed = 0;
const v = speed ?? 100; // 0 ✅

// Ignore seulement null/undefined
const x = "" ?? "default"; // ""
Cas d'usage : Valeur par défaut robuste (configs, options).
6️⃣ Optional Chaining (?.)
const city = user?.address?.city;

// Appel de fonction safe
user?.notify?.();

// Array safe
const first = arr?.[0];
Cas d'usage : Accès profond sans crash (APIs, données externes).
7️⃣ Switch (Énumération)
switch(role) {
    case 'admin':
        perm = 'ALL';
        break;
    case 'guest':
        perm = 'READ';
        break;
    default:
        perm = 'NONE';
}
Cas d'usage : Multiples cas d'égalité stricte.
8️⃣ Object Lookup (Strategy)
const permissions = {
    admin: 'ALL',
    guest: 'READ'
};
const perm = permissions[role] 
    ?? 'NONE';
Cas d'usage : Remplace switch. Plus propre, extensible O(1).
9️⃣ Guard Clauses (Early Return)
function process(user) {
    if (!user) return;
    if (!user.active) return;
    if (!user.verified) return;
    
    // Happy path ici
    doWork(user);
}
Cas d'usage : Éviter le "else hell". Validation en début de fonction.
🔟 Try / Catch / Finally
try {
    const data = JSON.parse(str);
    processData(data);
} catch (error) {
    logError(error);
} finally {
    cleanup(); // Toujours
}
Cas d'usage : Gestion d'erreurs (parsing, fetch, I/O).

📚 Explications Détaillées des Opérateurs Logiques

1️⃣ L'opérateur && (ET logique) - "Si ceci est vrai, fais cela"

Principe : L'opérateur && évalue de gauche à droite et s'arrête dès qu'il trouve une valeur falsy. Si tout est truthy, il retourne la dernière valeur.

// Si isLoggedIn est true, alors showDashboard() s'exécute
isLoggedIn && showDashboard();

// C'est l'équivalent de :
if (isLoggedIn) {
    showDashboard();
}
💡 En React on voit souvent ça :
{user && 

Bonjour {user.name}

} // Si user existe, on affiche le paragraphe
🎯 Cas d'usage typiques :
  • Rendu conditionnel dans React/Vue
  • Exécution de fonction uniquement si une condition est remplie
  • Chaînage de validations
2️⃣ L'opérateur || (OU logique) - "Prends ça, sinon prends ça par défaut"

Principe : L'opérateur || retourne la première valeur truthy qu'il rencontre. Si tout est falsy, il retourne la dernière valeur.

const name = userName || "Anonyme";
// Si userName existe, on prend userName, SINON on prend "Anonyme"

// C'est comme écrire :
const name = userName ? userName : "Anonyme";
⚠️ Le piège avec 0 et "" (chaîne vide)
const count = 0;
const val = count || 10; // Résultat: 10 😱

// Pourquoi ? Parce que 0 est considéré comme "faux" en JavaScript
// Donc JavaScript pense : "0 c'est faux, je prends 10 à la place"

const text = "";
const msg = text || "Aucun message"; // Résultat: "Aucun message"
// Même problème : "" est falsy !
✅ Quand utiliser || :
  • Valeurs par défaut pour des chaînes non-vides
  • Fallback sur des objets/tableaux
  • Quand 0, false, "" ne sont PAS des valeurs valides
3️⃣ L'opérateur ?? (Nullish Coalescing) - "La version safe"
🏆 La Règle d'Or

?? ne réagit qu'à null et undefined. Tout le reste est accepté !

const speed = 0;
const v = speed ?? 100; // Résultat: 0 ✅

// Pourquoi ? Parce que ?? ne réagit qu'à null et undefined
// 0, "", false sont considérés comme des valeurs valides !

const x = "" ?? "default"; // Résultat: "" ✅
const y = null ?? "default"; // Résultat: "default"
const z = undefined ?? "default"; // Résultat: "default"

📊 Comparaison || vs ??

// Les valeurs "fausses" en JavaScript (falsy values) :
// false, 0, "", null, undefined, NaN

// AVEC || (l'ancienne méthode problématique)
const avecOu = 0 || 10;        // 10 ❌ (perd notre 0)
const avecOu2 = "" || "rien";   // "rien" ❌ (perd la chaîne vide)
const avecOu3 = false || true;  // true ❌ (perd false)

// AVEC ?? (la bonne méthode)
const avecCoalesce = 0 ?? 10;        // 0 ✅ (garde notre 0)
const avecCoalesce2 = "" ?? "rien";   // "" ✅ (garde la chaîne vide)
const avecCoalesce3 = false ?? true;  // false ✅ (garde false)
const avecCoalesce4 = null ?? "default";  // "default" ✅
const avecCoalesce5 = undefined ?? "default";  // "default" ✅
✅ Cas d'usage parfaits pour ?? :
  • Configuration avec des valeurs numériques (timeout: 0 est valide)
  • Flags booléens (false est une valeur intentionnelle)
  • Chaînes vides acceptées ("" peut être un choix valide)
  • APIs qui retournent null/undefined pour "pas de données"
4️⃣ L'opérateur ?. (Optional Chaining) - "Pour éviter les erreurs"

Principe : L'opérateur ?. permet d'accéder à des propriétés imbriquées sans risquer une erreur si une propriété intermédiaire est null ou undefined.

// Sans ?. - La manière dangereuse ⚠️
if (user && user.address && user.address.city) {
    console.log(user.address.city);
}

// Avec ?. - La manière safe ✅
const city = user?.address?.city; 
// Si user ou address n'existe pas → city = undefined (pas d'erreur !)

🎯 Trois utilisations de ?.

// 1. Propriétés d'objets
const city = user?.address?.city;

// 2. Appel de fonction qui existe peut-être pas
user?.notify?.(); // Appelle notify() seulement si elle existe
obj.method?.();   // Safe même si method n'existe pas

// 3. Accès aux tableaux
const first = arr?.[0];     // Retourne undefined si arr n'existe pas
const item = list?.[index]; // Safe même si list est null
✅ Quand utiliser ?. :
  • Données venant d'APIs externes (structure incertaine)
  • Objets de configuration optionnels
  • Callbacks qui peuvent ne pas être définis
  • Accès à des propriétés profondes dans des objets complexes
⚠️ Attention : ?. ne remplace pas la validation
// ❌ Mauvais : masque un vrai problème
const result = data?.items?.map(x => x.value);
// Si data.items n'existe pas, result = undefined silencieusement

// ✅ Mieux : validation explicite quand c'est critique
if (!data?.items) {
    throw new Error("Items manquants dans la réponse API");
}
const result = data.items.map(x => x.value);

📋 Résumé des Opérateurs Logiques

&& : "Si ceci est vrai, fais cela"
Retourne la première valeur falsy, ou la dernière si tout est truthy
|| : "Prends ça, sinon prends ça par défaut" (mais attention à 0 et "")
Retourne la première valeur truthy, ou la dernière si tout est falsy
?? : "Prends ça, sinon prends ça par défaut" (sauf si c'est null/undefined)
Ne réagit QU'À null et undefined. Accepte 0, false, ""
?. : "Accède à cette propriété si elle existe, sinon undefined"
Évite les erreurs lors de l'accès à des propriétés profondes

🧭 Arbre de Décision : Quelle Structure Choisir ?

Assignation simple A ou B ?
condition ? A : B
Exécuter si condition vraie ?
cond && action()
Valeur par défaut (0 accepté) ?
val ?? default
Accès objet profond safe ?
obj?.prop?.sub
Multiples validations ?
Guard Clauses (return)
Énumération (5+ cas) ?
Object Lookup
Code risqué (parsing, I/O) ?
try / catch

⚠️ Pièges Courants

1. Oublier le break dans switch
switch(x) {
    case 1: console.log("Un"); // ⚠️ Pas de break
    case 2: console.log("Deux"); break;
}
// x=1 affiche "Un" ET "Deux" (fall-through)
2. Confondre || et ??
const config = { timeout: 0 };
const t1 = config.timeout || 5000; // 5000 ❌ (0 est falsy)
const t2 = config.timeout ?? 5000; // 0 ✅
3. Ternaire imbriqué illisible
// ❌ Cauchemar
const x = a ? (b ? (c ? 1 : 2) : 3) : 4;

// ✅ Utilisez if/else ou Object Lookup

🎮 Playground Interactif

Testez les différentes structures avec vos propres valeurs.

Ternaire
Short-Circuit
Nullish (??)
Optional (?. )
Guard Clause
Object Lookup
Sélectionnez un pattern et cliquez sur Exécuter
← Opérateurs Suivant: Boucles →