Scope & Fonctions Pures

Comprendre la portée des variables et l'architecture propre

Utilisez les flèches, cliquez ou glissez pour naviguer

Objectifs de la leçon

1. Comprendre les 3 niveaux de scope

Bloc, fonction, global

2. Identifier fonction pure vs impure

Effets de bord

3. Utiliser les valeurs par défaut

Paramètres optionnels

4. Composer des fonctions

Décomposer un problème complexe

Plan du cours

1

Les 3 niveaux de scope

Bloc, fonction, global — avec des exemples visuels

2

⚠️ Pourquoi les variables globales sont dangereuses

Effet de bord imprévisible

3

Fonctions pures

Même entrée → même sortie, pas d'effet de bord

4

Identifier pure vs impure

Exercice interactif avec les étudiants

5

Composer des fonctions

Chaque fonction fait UNE chose, on les assemble comme des tuyaux

Le Scope

La portée d'une variable

Où une variable est-elle accessible?

3 niveaux : bloc → fonction → global

Scope Global

⚠️ Variable déclarée en dehors de toute fonction

Accessible partout dans le code

let nom = "Alice"; // Variable globale

function saluer() {

console.log("Bonjour " + nom); // ✅ Accessible!

}

console.log(nom); // ✅ Accessible!

⚠️ Danger : Une variable globale peut être modifiée n'importe où!

Scope de Fonction

Variable déclarée DANS une fonction

Accessible seulement dans cette fonction

function calculer() {

let resultat = 10; // Scope de fonction

console.log(resultat); // ✅ Accessible

}

console.log(resultat); // ❌ Erreur! Hors scope

✅ La variable est "encapsulée" dans la fonction

Scope de Bloc

Variable déclarée avec let ou const dans un bloc

Accessible seulement dans ce bloc { }

if (true) {

let x = 5; // Scope de bloc

console.log(x); // ✅ Accessible

}

console.log(x); // ❌ Erreur! Hors du bloc

var

❌ Ignore le scope de bloc

let / const

✅ Respectent le scope de bloc

Les 3 niveaux de scope

Global

🌍 Partout

• Accessible partout

• ⚠️ Dangereux

Fonction

📦 Dans la fonction

• Encapsulée

• ✅ Recommandé

Bloc

🔒 Dans { }

• Le plus petit

• ✅ Le meilleur

🎯 Règle d'or : Scope le plus petit possible!

Exercice : Identifier le scope

let a = 1; // Scope ?

function test() {

let b = 2; // Scope ?

if (true) {

let c = 3; // Scope ?

}

}

a

Global 🌍

b

Fonction 📦

c

Bloc 🔒

⚠️ Danger : Variables Globales

Pourquoi c'est risqué?

Une variable globale peut être modifiée n'importe où

→ Effets de bord imprévisibles

❌ L'erreur : Modifier une variable globale

let compteur = 0; // Variable globale

function incrementer() {

compteur++; // Modifie la variable globale!

}

function reset() {

compteur = 0; // Modifie aussi!

}

⚠️ Problème :

Qui a modifié compteur? Difficile à tracer!

💡 Si deux fonctions utilisent compteur, elles interfèrent!

✅ La solution : Scope local

function creerCompteur() {

let compteur = 0; // Scope local!

return {

incrementer: () => ++compteur,

getValeur: () => compteur

};

}

✅ Chaque compteur est indépendant!

const c1 = creerCompteur();

const c2 = creerCompteur(); // c1 et c2 ne s'influencent pas

🎯 Règle d'or

Scope le plus petit possible

Déclarer les variables là où on en a besoin

❌ Éviter

Variables globales

✅ Préférer

Variables locales (let/const)

Fonctions Pures

La graine de la bonne architecture

Même entrée → même sortie

Pas d'effet de bord

Définition : Fonction Pure

✅ Critères

1️⃣ Même entrée = même sortie

2️⃣ Ne modifie rien à l'extérieur

3️⃣ Pas de dépendances externes

🎯 Avantages

✓ Prévisible

✓ Testable facilement

✓ Réutilisable

function double(n) {

return n * 2; // ✅ Pure! Toujours n*2 pour n

}

✅ Exemple : Fonction Pure

function additionner(a, b) {

return a + b;

}

Pourquoi c'est pur?

additionner(2, 3) retourne TOUJOURS 5

✅ Ne modifie aucune variable externe

✅ Ne dépend que de ses paramètres

// Testons plusieurs fois:

additionner(2, 3); // 5

additionner(2, 3); // 5

additionner(2, 3); // 5 - Toujours!

❌ Exemple : Fonction Impure

let taxe = 0.2; // Variable externe

function calculerPrix(prix) {

return prix * (1 + taxe); // Dépend de l'externe!

}

Pourquoi c'est impur?

❌ Dépend de la variable externe taxe

❌ Si taxe change, le résultat change

❌ Difficile à tester et prévoir

calculerPrix(100); // 120

taxe = 0.3; // On change la variable

calculerPrix(100); // 130 - Différent!

Pure vs Impure

✅ Pure

function add(a, b) {

return a + b;

}

• Même entrée → même sortie

• Pas d'effet de bord

• Prévisible & testable

❌ Impure

let total = 0;

function add(a, b) {

total = a + b; // Effet de bord!

}

• Modifie une variable externe

• Effet de bord

• Difficile à tracer

🎯 Fonction pure = prévisible, testable, réutilisable

Exercice Interactif

Pure ou Impure?

Analysez chaque fonction avec les étudiants

3 exemples à identifier

Exercice 1 : Pure ou Impure?

function multiplier(a, b) {

return a * b;

}

✅ Pure!

• Même entrée → même sortie

• Ne dépend de rien à l'extérieur

• Pas d'effet de bord

Exercice 2 : Pure ou Impure?

let compteur = 0;

function incrementer() {

compteur++;

}

❌ Impure!

• Modifie la variable externe compteur

• Effet de bord!

• Résultat différent à chaque appel

Exercice 3 : Pure ou Impure?

function saluer(nom) {

console.log("Bonjour " + nom);

return "Salutations!";

}

⚠️ Impure (techniquement)

console.log est un effet de bord

• Affiche quelque chose à l'extérieur

💡 Mais c'est OK pour le débogage! Pas dans les fonctions de calcul.

Composer des Fonctions

Comme des tuyaux qu'on connecte

Chaque fonction fait UNE chose

On les assemble pour des tâches complexes

Analogie : Le Pipeline

Entrée

100€

Fonction 1

+ TVA

Fonction 2

- Remise

Sortie

Prix final

💡 Le résultat d'une fonction devient l'entrée de la suivante!

Exemple : Pipeline de Prix

// 1️⃣ Ajouter la TVA

const ajouterTVA = (prix) => prix * 1.2;

// 2️⃣ Appliquer une remise

const appliquerRemise = (prix) => prix * 0.9;

// 3️⃣ Arrondir

const arrondir = (prix) => Math.round(prix);

✅ Chaque fonction fait UNE chose!

Simple, testable, réutilisable

Composons étape par étape

const prix = 100;

// 1️⃣

let resultat = ajouterTVA(prix); // 120

// 2️⃣

resultat = appliquerRemise(resultat); // 108

// 3️⃣

resultat = arrondir(resultat); // 108

💡 On peut enchaîner : arrondir(appliquerRemise(ajouterTVA(100)))

Créer une fonction composée

const calculerPrixFinal = (prix) =>

arrondir(

appliquerRemise(

ajouterTVA(prix)

)

);

🎯 Une nouvelle fonction qui combine les 3!

calculerPrixFinal(100); // 108

calculerPrixFinal(50); // 54

Piège #1 : Modifier sans s'en rendre compte

❌ On modifie une variable globale sans le vouloir

let total = 0;

function ajouter(n) {

total += n; // Modifie la variable globale!

}

✅ Solution : Retourner une nouvelle valeur

function ajouter(total, n) {

return total + n; // Pur!

}

Piège #2 : Confusion console.log

❌ "Pas de console.log" ≠ "Pas d'affichage"

❌ Mauvaise compréhension

"Les fonctions pures n'affichent rien"

✅ Réalité

"Les fonctions pures n'ont pas d'effet de bord"

💡 console.log est OK pour déboguer!

Mais pas dans les fonctions de calcul en production

Piège #3 : Composition trop abstraite

❌ La composition peut sembler abstraite pour les débutants

✅ Solution : Exemples concrets!

• Pipeline de prix (comme vu)

• Traitement de texte (majuscule → trim → couper)

• Transformation d'image (redimensionner → filtre → compresser)

💡 Montrer que chaque étape est simple et testable séparément!

Points clés à retenir

🎯 Scope le plus petit possible

Déclarer les variables là où on en a besoin

Fonction pure

Prévisible, testable, réutilisable

→ Graine de la bonne architecture

Composition

Résultat d'une fonction → entrée suivante

→ Comme des tuyaux connectés

✅ Éviter les variables globales

Préférer le scope local (let/const dans les fonctions)

À retenir!

Scope

Bloc < Fonction < Global

→ Le plus petit possible

Fonction pure

Même entrée = même sortie

→ Pas d'effet de bord

Variables globales

⚠️ Dangereuses

→ Effets imprévisibles

Composition

Fonctions comme tuyaux

→ Une chose à la fois

Questions?

Scope et fonctions pures = bases de l'architecture propre

Exercice pratique : Créer 3 fonctions pures et les composer!