0 XP
?
Débutant40 min25 XP

Objectifs de cette leçon

  • Définir une fonction avec function et =>
  • Comprendre les closures
  • Utiliser les callbacks

Fonctions en JavaScript 🧩

Les fonctions sont les briques fondamentales de JavaScript. Elles permettent d'organiser, de reutiliser et d'abstraire du code.


1. Les trois facons de creer des fonctions 🏗️

Declaration de fonction (function declaration)

function direBonjour(prenom) {
    return `Bonjour ${prenom}!`;
}

console.log(direBonjour("Alice")); // "Bonjour Alice!"

💡 Les declarations sont "hoistees" (levees) : elles sont disponibles partout dans le fichier, meme avant leur ligne de definition.

Expression de fonction

const direBonjour = function(prenom) {
    return `Bonjour ${prenom}!`;
};

console.log(direBonjour("Bob")); // "Bonjour Bob!"

⚠️ Les expressions ne sont PAS hoistees — elles doivent etre definies avant leur utilisation.

Fonctions flechees (arrow functions) — ES6

const direBonjour = (prenom) => {
    return `Bonjour ${prenom}!`;
};

// Version courte si une seule instruction
const double = (n) => n * 2;
console.log(double(5)); // 10

// Un seul parametre : les parentheses sont optionnelles
const carrer = n => n * n;

// Aucun parametre : parentheses obligatoires
const salut = () => "Bonjour !";

2. Comparaison des trois styles 📊

CaracteristiqueDeclarationExpressionArrow function
HoistingOuiNonNon
Syntaxefunction nom()const nom = function()const nom = () =>
thisDynamiqueDynamiqueLexical (parent)
ArgumentsDisponiblesDisponiblesNon disponibles
UsageFonctions nommeesVariables de fonctionCallbacks, fonctions courtes

3. Parametres et arguments 📥

Parametres par defaut

function saluer(prenom = "Inconnu", age = 0) {
    return `${prenom} a ${age} ans.`;
}

console.log(saluer("Alice", 25)); // "Alice a 25 ans."
console.log(saluer());             // "Inconnu a 0 ans."
console.log(saluer("Bob"));       // "Bob a 0 ans."

Parametres rest (rest parameters)

function somme(...nombres) {
    let total = 0;
    for (const n of nombres) {
        total += n;
    }
    return total;
}

console.log(somme(1, 2, 3));      // 6
console.log(somme(1, 2, 3, 4, 5)); // 15

Destructuration des parametres

function afficherPersonne({ nom, age, ville = "Inconnue" }) {
    console.log(`${nom}, ${age} ans, ${ville}`);
}

afficherPersonne({ nom: "Alice", age: 25 }); // "Alice, 25 ans, Inconnue"
afficherPersonne({ nom: "Bob", age: 30, ville: "Paris" }); // "Bob, 30 ans, Paris"

4. La portee des variables (scope) 🌍

const global = "Je suis global";

function maFonction() {
    const local = "Je suis local";
    console.log(global);   // ✅ Accessible
    console.log(local);    // ✅ Accessible
}

maFonction();
console.log(global);  // ✅ Accessible
// console.log(local); // ❌ ReferenceError : local n'existe pas ici

// Bloc scope avec let/const
if (true) {
    const cache = "je suis dans un bloc";
}
// console.log(cache); // ❌ ReferenceError
VariablePorteeReassignableAccessible hors du bloc
constBloc {}NonNon
letBloc {}OuiNon
varFonction ()OuiOui (problem !)

5. Les closures (fermetures) 🔒

Une closure c'est quand une fonction "se souvient" des variables de son environnement d'origine, meme apres avoir ete执行e ailleurs.

function creerCompteur() {
    let count = 0;  // Variable dans la portee de creerCompteur
    return {
        incrementer: () => ++count,
        obtenir: () => count
    };
}

const compteur = creerCompteur();
console.log(compteur.incrementer()); // 1
console.log(compteur.incrementer()); // 2
console.log(compteur.obtenir());     // 2
// count n'est PAS accessible directement

💡 La closure "ferme" sur la variable count. Meme quand creerCompteur() a fini de s'executer, la fonction retournee a toujours acces a count.

Exemple concret : usine de fonctions

function creerMultiplieur(multiplicateur) {
    return (nombre) => nombre * multiplicateur;
}

const doubler = creerMultiplieur(2);
const tripler = creerMultiplieur(3);

console.log(doubler(5));  // 10
console.log(tripler(5));  // 15

6. Les callbacks (fonctions de rappel) 📞

Un callback est une fonction passee en argument a une autre fonction, qui sera appelee plus tard :

function calculer(a, b, operation) {
    return operation(a, b);
}

const addition = (x, y) => x + y;
const multiplication = (x, y) => x * y;

console.log(calculer(5, 3, addition));       // 8
console.log(calculer(5, 3, multiplication)); // 15

Callbacks avec des methods de tableau

const nombres = [1, 2, 3, 4, 5];

// forEach — parcourir chaque element
nombres.forEach((n) => {
    console.log(n);
});

// map — transformer chaque element
const doubles = nombres.map((n) => n * 2);
console.log(doubles); // [2, 4, 6, 8, 10]

// filter — filtrer les elements
const pairs = nombres.filter((n) => n % 2 === 0);
console.log(pairs); // [2, 4]

// reduce — reduire a une seule valeur
const somme = nombres.reduce((acc, n) => acc + n, 0);
console.log(somme); // 15

7. Les IIFE (Immediately Invoked Function Expressions) ⚡

Une IIFE s'execute immediatement apres sa definition :

// Syntaxe classique
(function() {
    const message = "Je suis dans une IIFE";
    console.log(message);
})();

// Arrow function IIFE
(() => {
    console.log("IIFE avec arrow function");
})();

💡 Les IIFE sont utiles pour creer un scope isole et eviter de polluer l'espace global.


8. Le mot-cle this 🔎

this depend du contexte d'appel :

// Dans une fonction classique
function MaFonction() {
    console.log(this); // window (global) ou undefined (strict mode)
}

// Dans un objet
const obj = {
    nom: "Alice",
    direBonjour() {
        console.log(`Bonjour, je suis ${this.nom}`); // this.nom = "Alice"
    }
};

// Dans une arrow function — this est le parent lexical
const obj2 = {
    nom: "Bob",
    direBonjour: () => {
        console.log(this.nom); // undefined !箭头函数没有自己的this
    }
};

⚠️ Regle importante : Les arrow functions n'ont PAS leur propre this. Ils heritent du this du contexte parent. C'est pour ca qu'on ne les utilise PAS comme methodes d'objets.


9. Synthese des types de fonctions ⚙️

// 1. Declaration
function greet(name) {
    return `Hello ${name}`;
}

// 2. Expression
const greet2 = function(name) {
    return `Hello ${name}`;
};

// 3. Arrow function
const greet3 = (name) => `Hello ${name}`;

// 4. Parametres par defaut
const greet4 = (name = "World") => `Hello ${name}`;

// 5. Rest parameters
function sum(...nums) {
    return nums.reduce((a, b) => a + b, 0);
}

// 6. IIFE
(() => {
    console.log("Execute immediatement !");
})();

// 7. Callback
setTimeout(() => {
    console.log("Execute apres 1 seconde");
}, 1000);

10. Exercices pour toi 🎯

Exercice 1 : Calculatrice Cree une fonction calculer(a, b, operateur) qui prend deux nombres et un operateur (+, -, *, /) et retourne le resultat.

Exercice 2 : Compteur avec closure Cree une fonction creerCompteur(depart) qui retourne un objet avec incrementer() et decrementer().

Exercice 3 : Pipe function Cree une fonction pipe(f1, f2, f3) qui applique successivement f1, f2, f3 a une valeur :

const ajouter2 = x => x + 2;
const doubler = x => x * 2;
const carrer = x => x * x;

const maFonction = pipe(ajouter2, doubler, carrer);
console.log(maFonction(3)); // ((3 + 2) * 2) ^ 2 = 100

⚡ Simulateur — Fonctions

Étape 1/9
📝 Pseudo-code
1function add(a, b) {
2 return a + b;
3}
4const multiply = (a, b) => a * b;
5console.log(add(3, 5));
6console.log(multiply(4, 6));
⚙️ Exécution
📦 Mémoire
Aucune variable
🔀 Flux d'exécution
function add()
3
Déclaration de fonction

function add(a, b) définit une fonction avec la syntaxe classique. Les paramètres a et b reçoivent les valeurs lors de l'appel.