Polar Code 🎭

Command Palette

Search for a command to run...

05
Pièce N°05

Module 5 -- Fonctions : Les Super-Pouvoirs Cachés

Prêt à passer de l'autre côté ? Jusqu'ici, tu suivais des ordres. Les fonctions, c'est la magie noire qui te permet d'écrire tes propres règles, de les réutiliser dans l'ombre, et de rendre ton code imprévisible et efficace.

Pense aux fonctions comme à des plans d'action :

  • Tu définis le plan une fois (function nettoyerScene())
  • Quand c'est le moment, tu l'exécutes (nettoyerScene())
  • Tu peux adapter le plan (nettoyerScene("empreintes", "fibres"))
  • Le plus beau : tu peux créer des plans qui en appellent d'autres !

Dans ce module:

  1. Les bases : comment déclarer et lancer une opération
  2. Les outils modernes : les raccourcis qui effacent les traces
  3. Les concepts avancés : ce qui fait vraiment la puissance des ombres

Accroche-toi, c'est là que ton code devient dangereux.


5.1 Fonctions Fondamentales - Les Plans de Base

Déclaration vs Expression : Deux façons de graver un plan

// MÉTHODE 1 : Déclaration (tu annonces le plan à voix haute)
function preparerPlanque() {
  return "Planque activée.";
}
// Particularité : tu peux l'appeler AVANT dans le code. Comme une prophétie.

// MÉTHODE 2 : Expression (tu écris le plan et le caches)
const preparerFuite = function() {
  return "Itinéraire sécurisé.";
};
// Particularité : tu dois d'abord créer la cache avant de l'utiliser.

// En pratique : la déclaration est plus directe, l'expression plus discrète.

Paramètres et Arguments : Personnaliser l'Opération

// Les paramètres, ce sont les "éléments variables" du plan
function monterCoup(cible, moyen, couverture) {
  return `Cible : ${cible}. Moyen : ${moyen}. Couverture : ${couverture}.`;
}

// Les arguments, c'est ce que tu injectes QUAND tu exécutes
const operation = monterCoup("banque", "dynamite", "tunnel");
// "banque", "dynamite", "tunnel" sont les arguments

console.log(operation); // "Cible : banque. Moyen : dynamite. Couverture : tunnel."

// Tu peux appeler avec moins d'arguments
monterCoup("bijouterie"); // "Cible : bijouterie. Moyen : undefined. Couverture : undefined."

Valeur de Retour : Ce que l'Opération "Rapporte"

// Une fonction SANS return : elle agit, mais ne "rend" rien
function surveiller(cible) {
  console.log(`Surveillance de ${cible} en cours...`);
  // Pas de return → la valeur est "undefined"
}

let rapport = surveiller("l'entrepôt");
console.log(rapport); // undefined

// Une fonction AVEC return : elle agit et rapporte
function calculerPart(butein, parts) {
  let part = butin / parts;
  return part; // ⬅️ C'est ce qu'on récupère
}

let maPart = calculerPart(100000, 4);
console.log(maPart); // 25000

Portée des Variables : Qui Voit Quoi ?

let variableRue = "Je suis dans la rue. Tout le monde me voit.";

function testOmbre() {
  let variableChambre = "Je suis dans la chambre. Seulement les initiés.";
  
  console.log(variableRue); // ✅ Je vois la rue
  console.log(variableChambre);  // ✅ Je vois la chambre
}

testOmbre();
console.log(variableRue); // ✅ Toujours dans la rue
console.log(variableChambre);  // ❌ ERREUR ! variableChambre n'existe pas ici

// Métaphore du bunker :
// - Variables globales = dans la rue
// - Variables locales = dans la salle secrète

Hoisting : Le "Lévitage" des Plans

// ÉTRANGE MAIS VRAI : Ce code FONCTIONNE
alerte(); // "Plan B activé."

function alerte() {
  console.log("Plan B activé.");
}

// Parce que JavaScript "lève" (hoist) les DÉCLARATIONS de fonctions
// Le moteur réécrit ton code dans l'ombre :

function alerte() {          // 1. Met la fonction en haut
  console.log("Plan B activé.");
}

alerte();                    // 2. Puis exécute

// ATTENTION : ça casse avec les expressions !
// alerte2(); // ❌ ERREUR !

const alerte2 = function() {
  console.log("Plan C.");
};

5.2 Fonctions Modernes - Les Raccourcis de l'Ombre (ES6+)

Fonctions Fléchées : La Syntaxe Tranchante

// ANCIENNE FAÇON
const addition = function(a, b) {
  return a + b;
};

// NOUVELLE FAÇON (arrow function)
const addition = (a, b) => {
  return a + b;
};

// ENCORE PLUS COURT (une seule ligne avec return)
const addition = (a, b) => a + b;

// Un seul paramètre ? Pas de parenthèses.
const carre = x => x * x;

// Aucun paramètre ? Parenthèses vides.
const signal = () => "Tout est calme.";

// ATTENTION : Les flèches n'ont pas leur propre "this".
// (On verra "this" plus tard. C'est à la fois une faille et une arme.)

Paramètres par Défaut : Les Valeurs de Secours

// Avant ES6 : vérifier à la main
function contacter(indic) {
  indic = indic || "Fantôme"; // Si indic falsy, utilise "Fantôme"
  return `Contact : ${indic}`;
}

// Après ES6 : plus propre.
function contacter(indic = "Fantôme", code = "Nuit") {
  return `Contact : ${indic}. Code : ${code}.`;
}

console.log(contacter("Mole")); // "Contact : Mole. Code : Nuit."
console.log(contacter());        // "Contact : Fantôme. Code : Nuit."

Rest Parameters (...) : Attraper le Reste

// Comment faire avec un nombre variable d'éléments ?
function listeCibles(...cibles) { // ⬅️ Les "..." capturent TOUT
  console.log(`Cibles identifiées : ${cibles.join(', ')}`);
}

listeCibles("gare", "banque", "musée");
// cibles = ["gare", "banque", "musée"]

// Peut se combiner avec des paramètres normaux
function profil(nom, ...traits) {
  console.log(`${nom} : ${traits.join(', ')}`);
}

profil("Rico", "imprévisible", "violent", "silencieux");
// nom = "Rico", traits = ["imprévisible", "violent", "silencieux"]

Spread Operator (...) : L'Inverse du Rest

// Spread = ÉTALER une liste ou un objet

// 1. Avec les tableaux
let armes = ["revolver", "corde"];
let outils = ["pinces", "lampe"];
let sac = [...armes, "gants", ...outils];
console.log(sac); // ["revolver", "corde", "gants", "pinces", "lampe"]

// 2. Avec les fonctions
function calcul(a, b, c) {
  return a + b + c;
}

let chiffres = [10, 20, 30];
console.log(calcul(...chiffres)); // 60
// Équivalent à : calcul(10, 20, 30)

// 3. Copier un tableau (sans laisser de lien)
let original = [1, 2, 3];
let copie = [...original]; // Nouveau tableau. Indépendant.

Décomposition (Destructuring) des Paramètres

// Au lieu de prendre un objet et fouiller dedans...
function analyserDossier(dossier) {
  console.log(`${dossier.suspect}, risque ${dossier.niveau}`);
}

// ... on peut DÉCOMPOSER direct dans les paramètres !
function analyserDossier({ suspect, niveau, ville = "Inconnue" }) {
  console.log(`${suspect}, risque ${niveau}, dernière vue : ${ville}`);
}

let fiche = { suspect: "Kowalski", niveau: 8 };
analyserDossier(fiche); // "Kowalski, risque 8, dernière vue : Inconnue"

// Pareil avec les tableaux !
function coordonnees([x, y]) {
  console.log(`Point de rencontre : ${x}, ${y}`);
}

let rdv = [45, -73];
coordonnees(rdv); // "Point de rencontre : 45, -73"

5.3 Concepts Avancés - La Puissance de l'Ombre

Fonctions d'Ordre Supérieur : Des Fonctions qui Manipulent des Fonctions

// Une fonction qui REÇOIT une fonction en paramètre
function executerOperation(valeur, operation) {
  return operation(valeur); // J'appelle la fonction qu'on m'a donnée
}

// Des fonctions "simples" à passer
function doubler(x) { return x * 2; }
function anonymiser(x) { return "***"; }

// Utilisation
console.log(executerOperation(100, doubler));    // 200
console.log(executerOperation("nom", anonymiser)); // "***"

// Les méthodes de tableau sont des fonctions d'ordre supérieur !
[10, 20, 30].map(doubler); // [20, 40, 60]

Fermetures (Closures) : La Mémoire Fantôme

// Une closure, c'est une fonction qui "se souvient" de là où elle est née
function creerCompteur() {
  let compte = 0; // Variable "fantôme", invisible de l'extérieur
  
  // La fonction interne voit "compte"
  return function() {
    compte += 1;
    return compte;
  };
}

// Chaque compteur a SON PROPRE "compte"
let monCompte = creerCompteur();
let tonCompte = creerCompteur();

console.log(monCompte()); // 1
console.log(monCompte()); // 2
console.log(tonCompte()); // 1 (indépendant !)
console.log(monCompte()); // 3

// VRAIMENT utile : créer des fonctions "personnalisées"
function creerMultiplicateur(facteur) {
  return function(valeur) {
    return valeur * facteur;
  };
}

let doubler = creerMultiplicateur(2);
let tripler = creerMultiplicateur(3);

console.log(doubler(500)); // 1000
console.log(tripler(500)); // 1500

IIFE : Exécuter un Plan et Effacer les Traces

// Parfois tu veux exécuter du code une fois, sans laisser de nom
// IIFE = Immediately Invoked Function Expression

// Syntaxe :
(function() {
  let message = "Ce code s'exécute et disparaît.";
  console.log(message);
})(); // Les () à la fin déclenchent l'exécution IMMÉDIATE

// Usage classique : créer une chambre noire
let résultat = (function(a, b) {
  return a + b;
})(5, 3); // S'exécute direct, résultat = 8

console.log(résultat); // 8

Récursivité : Quand une Fonction s'Appelle Elle-Même

// Une fonction récursive, c'est comme un miroir face à un miroir :
// Elle contient une version plus petite d'elle-même

// Exemple classique : compteur à retardement
// 5... 4... 3... 2... 1...
function compteARebours(n) {
  if (n <= 0) {
    console.log("BOOM."); // CAS DE BASE (pour éviter l'infini)
    return;
  }
  console.log(`${n}...`);
  compteARebours(n - 1); // APPEL RÉCURSIF
}

compteARebours(5);
// 5...
// 4...
// 3...
// 2...
// 1...
// BOOM.

Fonctions Pures et Effets de Bord

// FONCTION PURE (propre)
// 1. Mêmes arguments → toujours même résultat
// 2. Pas d'effets de bord (ne modifie rien à l'extérieur)
function additionPropre(a, b) {
  return a + b; // Juste un calcul. Rien ne bouge ailleurs.
}

// FONCTION SALE (avec effets de bord)
let totalExterne = 0;

function additionSale(a, b) {
  totalExterne = a + b; // ⚠️ Modifie une variable extérieure !
  console.log("Opération sale."); // ⚠️ Laisse une trace.
  return a + b;
}

// POURQUOI C'EST IMPORTANT ?
// Les fonctions pures sont :
// - Plus faciles à nier
// - Plus prévisibles
// - Meilleures pour rester dans l'ombre
// - Parallélisables

// Les effets de bord (écrire un fichier, appeler un contact, modifier une preuve)
// sont nécessaires, mais garde-les dans des fonctions bien marquées.

Pour résumer ce module :

  • Fonctions de base → Créer des plans réutilisables
  • Fonctions modernes → Écrire moins, agir plus avec ES6+
  • Concepts avancés → Comprendre la vraie puissance de l'ombre

Les fonctions, c'est le cœur de l'opération. Maîtrise-les, et tu pourras tout faire disparaître.