Cours JavaScript et TypeScript · Module 2: Fonctions, tableaux et objets

La portée des variables (globale, de fonction, de bloc)

12 min de lecture
Dans cette leçon8

Bon retour à Jurassic Park ! Aujourd'hui, nous allons nous pencher sur l'un des concepts fondamentaux de JavaScript - la portée des variables. Comprendre la portée des variables est essentiel pour écrire du code efficace, sûr et prévisible, en particulier dans des systèmes complexes comme notre parc rempli de dinosaures.

Qu'est-ce que la portée des variables ?

La portée des variables (scope) détermine où, dans le code, une variable donnée est accessible - autrement dit, depuis quel endroit du code on peut y faire référence. Tout comme Jurassic Park possède des zones avec différents niveaux d'accès (la zone des visiteurs, le laboratoire réservé aux scientifiques, les enclos qui exigent des autorisations spéciales), JavaScript possède différentes portées d'accès aux variables.

En JavaScript, on distingue trois grands types de portée :

  1. La portée globale (Global scope)
  2. La portée de fonction (Function scope)
  3. La portée de bloc (Block scope)

La portée globale

Les variables définies en dehors de toute fonction ou de tout bloc de code ont une portée globale. Cela signifie qu'elles sont accessibles dans tout le programme, dans chaque fonction et dans chaque bloc de code.

1// Variables globales - accessibles partout, comme les informations publiques sur le parc
2const parkName = "Jurassic Park";
3let visitorCount = 0;
4var isOpenToPublic = true;
5
6function checkParkStatus() {
7  console.log(`Nom du parc : ${parkName}`);
8  console.log(`Nombre de visiteurs : ${visitorCount}`);
9  console.log(`Ouvert au public : ${isOpenToPublic}`);
10}
11
12function updateVisitorCount(newCount) {
13  // On peut modifier une variable globale depuis n'importe quelle fonction
14  visitorCount = newCount;
15  console.log(`Nombre de visiteurs mis à jour : ${visitorCount}`);
16}
17
18// Appel des fonctions qui utilisent les variables globales
19checkParkStatus();
20updateVisitorCount(250);
21checkParkStatus();

Il faut être prudent avec les variables globales, car :

  • Elles peuvent être modifiées par accident depuis n'importe quel endroit du code
  • Elles peuvent provoquer des conflits de noms
  • Elles compliquent le suivi de l'état de l'application
  • Elles augmentent le couplage entre les différentes parties du code

Dans notre parc, les variables globales sont comme des documents accessibles à tous les employés - elles sont parfois indispensables, mais un trop grand nombre de ces documents peut mener au désordre et aux malentendus.

La portée de fonction

Les variables définies à l'intérieur d'une fonction ne sont accessibles qu'à l'intérieur de cette fonction. Ce sont des variables locales à cette fonction.

1function monitorDinosaur(dinoId) {
2  // Ces variables ont une portée de fonction - elles ne sont accessibles qu'à l'intérieur de cette fonction
3  const startTime = Date.now();
4  let status = "Surveillance...";
5  var sensorData = [];
6
7  // On peut utiliser les variables à l'intérieur de la fonction
8  status = "Collecte des données...";
9  sensorData.push({ time: startTime, temperature: 37.5 });
10
11  console.log(`Statut : ${status}`);
12  console.log(`Données des capteurs : ${JSON.stringify(sensorData)}`);
13
14  // On renvoie le résultat
15  return {
16    id: dinoId,
17    monitoringStarted: startTime,
18    lastStatus: status
19  };
20}
21
22// Appel de la fonction
23const monitoringResults = monitorDinosaur("T-Rex-01");
24
25// Le code ci-dessous provoquerait une erreur, car on essaie d'accéder
26// à des variables de portée de fonction depuis l'extérieur de la fonction
27// console.log(startTime);    // ReferenceError
28// console.log(status);       // ReferenceError
29// console.log(sensorData);   // ReferenceError
30
31// Mais on a accès à la valeur renvoyée par la fonction
32console.log(monitoringResults);

La portée de fonction fonctionne comme les zones réservées du parc - seul le personnel autorisé (le code à l'intérieur de la fonction) a accès aux informations et aux ressources de cette zone.

La différence entre var, let et const dans le contexte de la portée de fonction

Les trois mots-clés (var, let, const) créent tous des variables de portée de fonction, mais il existe entre eux une différence importante :

  • var a une portée de fonction, mais pas de bloc
  • let et const ont à la fois une portée de fonction et une portée de bloc

Voyons cela sur un exemple :

1function securityCheck() {
2  // Toutes ces variables sont accessibles dans toute la fonction
3  var securityCode = "A1B2C3";
4  let accessLevel = 5;
5  const securityChief = "Robert Muldoon";
6
7  if (accessLevel >= 5) {
8    var emergencyProtocol = "Code Red"; // portée de fonction !
9    let backupSystem = "Operational";   // portée de bloc
10    const safeRoom = "Bunker B";        // portée de bloc
11
12    console.log(securityCode);    // A1B2C3 - accessible
13    console.log(accessLevel);     // 5 - accessible
14    console.log(securityChief);   // Robert Muldoon - accessible
15  }
16
17  console.log(emergencyProtocol); // Code Red - accessible bien que définie dans le bloc if
18  // console.log(backupSystem);   // ReferenceError - la variable a une portée de bloc
19  // console.log(safeRoom);       // ReferenceError - la variable a une portée de bloc
20}
21
22securityCheck();

La portée de bloc

La portée de bloc a été introduite dans ES6 (ES2015) avec les nouveaux mots-clés let et const. Les variables définies avec let et const à l'intérieur d'un bloc de code (délimité par des accolades {}) ne sont accessibles qu'à l'intérieur de ce bloc.

1function monitorDinosaurBehavior() {
2  let dangerLevel = 0;
3
4  // Bloc if - crée une nouvelle portée
5  if (true) {
6    // Portée de bloc - variables accessibles uniquement à l'intérieur de ce bloc
7    let behavior = "Calme";
8    const vitals = { heartRate: 80, temperature: 38 };
9
10    // Modification d'une variable de la portée extérieure
11    dangerLevel = behavior === "Agressif" ? 5 : 1;
12
13    console.log(behavior);     // Calme - accessible
14    console.log(vitals);       // { heartRate: 80, temperature: 38 } - accessible
15    console.log(dangerLevel);  // 1 - accessible
16  }
17
18  console.log(dangerLevel);    // 1 - accessible car définie dans une portée plus large
19  // console.log(behavior);    // ReferenceError - la variable a une portée de bloc
20  // console.log(vitals);      // ReferenceError - la variable a une portée de bloc
21
22  // Bloc for - crée lui aussi une nouvelle portée
23  for (let i = 0; i < 5; i++) {
24    // 'i' a une portée de bloc, accessible uniquement à l'intérieur de la boucle
25    const sensorId = `Sensor-${i}`;
26    console.log(sensorId);
27  }
28
29  // console.log(i);        // ReferenceError - 'i' a une portée de bloc
30  // console.log(sensorId); // ReferenceError - la variable a une portée de bloc
31}
32
33monitorDinosaurBehavior();

La portée de bloc ressemble aux différents enclos de notre parc - chaque enclos a ses propres règles et son propre accès, et l'équipement attribué à un enclos n'est pas disponible dans les autres enclos.

La différence entre var, let et const

Nous pouvons maintenant mieux comprendre les différences entre ces trois mots-clés :

  1. var :

    • A une portée de fonction ou globale, mais pas de bloc
    • Peut être redéclarée plusieurs fois
    • Peut être modifiée
    • Est remontée (hoisting) avec la valeur undefined
  2. let :

    • A une portée de bloc
    • Ne peut pas être redéclarée dans la même portée
    • Peut être modifiée
    • Est remontée (hoisting) sans valeur affectée (zone morte temporelle)
  3. const :

    • A une portée de bloc
    • Ne peut pas être redéclarée dans la même portée
    • Ne peut pas être modifiée (mais les propriétés des objets peuvent être modifiées)
    • Est remontée (hoisting) sans valeur affectée (zone morte temporelle)
1function demonstrateVariables() {
2  // var
3  var dinosaur = "T-Rex";
4  var dinosaur = "Velociraptor"; // OK - on peut redéclarer
5  dinosaur = "Triceratops";      // OK - on peut modifier
6
7  // let
8  let park = "Jurassic Park";
9  // let park = "Dino World";    // Erreur - on ne peut pas redéclarer
10  park = "Jurassic World";       // OK - on peut modifier
11
12  // const
13  const island = "Isla Nublar";
14  // const island = "Isla Sorna"; // Erreur - on ne peut pas redéclarer
15  // island = "Another Island";   // Erreur - on ne peut pas modifier
16
17  // Mais les propriétés des objets const peuvent être modifiées
18  const parkSystem = {
19    mainPower: true,
20    backupGenerator: false
21  };
22
23  // Ceci est autorisé
24  parkSystem.mainPower = false;
25  parkSystem.backupGenerator = true;
26
27  console.log(parkSystem); // { mainPower: false, backupGenerator: true }
28}
29
30demonstrateVariables();

La portée lexicale et les fermetures (closures)

JavaScript utilise la portée lexicale, ce qui signifie que les fonctions peuvent accéder aux variables définies dans leur portée extérieure.

1function initSecuritySystem() {
2  // Variables dans la portée de la fonction extérieure
3  const systemName = "JurassicSafe";
4  let isActive = false;
5  let alertLevel = 0;
6
7  // La fonction intérieure a accès aux variables de la fonction extérieure
8  function activateSystem() {
9    isActive = true;
10    console.log(`Le système ${systemName} a été activé.`);
11    return true;
12  }
13
14  // Encore une fonction intérieure
15  function setAlertLevel(level) {
16    alertLevel = level;
17    console.log(`Système ${systemName} : niveau d'alerte réglé sur ${alertLevel}`);
18  }
19
20  // On renvoie les fonctions intérieures
21  return {
22    activate: activateSystem,
23    setAlert: setAlertLevel,
24    getStatus: function() {
25      return {
26        name: systemName,
27        active: isActive,
28        alertLevel: alertLevel
29      };
30    }
31  };
32}
33
34// On crée une instance du système de sécurité
35const securitySystem = initSecuritySystem();
36
37// On utilise les fonctions renvoyées
38securitySystem.activate();           // Le système JurassicSafe a été activé.
39securitySystem.setAlert(3);          // Système JurassicSafe : niveau d'alerte réglé sur 3
40console.log(securitySystem.getStatus()); // { name: "JurassicSafe", active: true, alertLevel: 3 }

Dans l'exemple ci-dessus, les fonctions intérieures créent une fermeture (closure) sur les variables de la fonction initSecuritySystem. Même une fois l'exécution de initSecuritySystem terminée, les fonctions renvoyées ont toujours accès à ces variables.

Les fermetures sont comme les équipes de sécurité du parc - même quand elles quittent le centre de commandement, elles ont toujours accès aux codes et aux protocoles qu'elles ont emportés avec elles.

Exemple pratique : un système de gestion du parc

Créons un exemple plus complet, qui montre les différentes portées des variables dans le contexte d'un système de gestion du parc :

1// Variables globales - accessibles dans tout le programme
2const PARK_NAME = "Jurassic Park";
3let parkStatus = "closed";
4var totalVisitors = 0;
5
6// Fonction IIFE (Immediately Invoked Function Expression) qui crée un module
7const parkSystem = (function() {
8  // Variables privées - portée de fonction, inaccessibles hors du module
9  let securityStatus = "active";
10  let powerStatus = "online";
11  const MAX_CAPACITY = 2000;
12
13  // Fonction utilitaire privée
14  function checkSystemStatus() {
15    return powerStatus === "online" && securityStatus === "active";
16  }
17
18  // API publique du module
19  return {
20    // Méthode qui ouvre le parc aux visiteurs
21    openPark: function() {
22      if (checkSystemStatus()) {
23        parkStatus = "open"; // Modification d'une variable globale
24        console.log(`${PARK_NAME} est maintenant ouvert aux visiteurs !`);
25        return true;
26      } else {
27        console.log("Impossible d'ouvrir le parc - les systèmes de sécurité ne sont pas pleinement opérationnels.");
28        return false;
29      }
30    },
31
32    // Méthode qui enregistre de nouveaux visiteurs
33    registerVisitors: function(count) {
34      // Vérification de la capacité du parc
35      if (parkStatus !== "open") {
36        console.log("Le parc est fermé. Impossible d'enregistrer des visiteurs.");
37        return false;
38      }
39
40      // Variable de portée de bloc
41      const availableCapacity = MAX_CAPACITY - totalVisitors;
42
43      if (count <= availableCapacity) {
44        totalVisitors += count; // Modification d'une variable globale
45        console.log(`${count} nouveaux visiteurs enregistrés. Total : ${totalVisitors}`);
46
47        // Portée de bloc à l'intérieur de la condition
48        if (totalVisitors > MAX_CAPACITY * 0.8) {
49          const warningMessage = "Attention : le parc approche de sa capacité maximale !";
50          console.log(warningMessage);
51        }
52
53        return true;
54      } else {
55        console.log(`Erreur : trop de visiteurs. Capacité disponible : ${availableCapacity}`);
56        return false;
57      }
58    },
59
60    // Méthode qui ferme le parc
61    closePark: function() {
62      // Fonction locale qui a accès aux variables d'une portée plus large
63      function evacuateVisitors() {
64        console.log(`Évacuation de ${totalVisitors} visiteurs du parc...`);
65        totalVisitors = 0;
66      }
67
68      parkStatus = "closed";
69      evacuateVisitors();
70      console.log(`${PARK_NAME} a été fermé.`);
71
72      return true;
73    },
74
75    // Méthode qui change le statut des systèmes
76    updateSystems: function(power, security) {
77      // Pour démontrer let contre var
78      if (power) {
79        let localMessage = "Mise à jour du système d'alimentation...";
80        console.log(localMessage);
81        powerStatus = power;
82      }
83
84      if (security) {
85        var statusMessage = "Mise à jour du système de sécurité...";
86        console.log(statusMessage);
87        securityStatus = security;
88      }
89
90      // console.log(localMessage); // Erreur : localMessage a une portée de bloc
91      console.log(statusMessage);  // Fonctionne : statusMessage a une portée de fonction
92
93      return {
94        power: powerStatus,
95        security: securityStatus
96      };
97    }
98  };
99})();
100
101// Utilisation de notre système
102console.log(`Statut du parc avant l'ouverture : ${parkStatus}`);
103parkSystem.openPark();
104console.log(`Statut du parc après l'ouverture : ${parkStatus}`);
105
106parkSystem.registerVisitors(500);
107parkSystem.registerVisitors(1200);  // Devrait afficher un avertissement sur la capacité
108parkSystem.registerVisitors(400);   // Devrait afficher une erreur de dépassement de capacité
109
110// Mise à jour des systèmes
111parkSystem.updateSystems("offline", null);
112parkSystem.openPark(); // Devrait afficher une erreur - impossible d'ouvrir le parc
113
114// Rétablissement des systèmes et fermeture du parc
115parkSystem.updateSystems("online", "active");
116parkSystem.closePark();
117console.log(`Statut du parc après la fermeture : ${parkStatus}`);
118console.log(`Nombre de visiteurs après l'évacuation : ${totalVisitors}`);
119
120// Tentative d'accès aux variables privées
121// console.log(securityStatus); // Erreur : variable inaccessible
122// console.log(MAX_CAPACITY);   // Erreur : variable inaccessible

Les bonnes pratiques

  1. Évite les variables globales - comme dans un vrai parc, plus il y a de zones publiques, plus il est difficile de les surveiller et de les sécuriser.

  2. Préfère const à let, et let à var - la plupart des variables ne devraient pas changer de valeur, et si elles le font, elles devraient avoir la portée la plus réduite possible.

  3. Utilise la portée de bloc - limite la visibilité des variables à la plus petite portée possible.

  4. Applique le pattern module - encapsule les variables et les fonctions dans des modules, en n'exposant que l'API nécessaire.

  5. Garde les fermetures à l'esprit - les fermetures sont un outil puissant, mais elles peuvent provoquer des fuites de mémoire si elles sont mal utilisées.

Résumé

La portée des variables en JavaScript ressemble au système de zones d'accès de Jurassic Park :

  • Portée globale - comme les zones publiques du parc, accessibles à tous
  • Portée de fonction - comme les zones réservées à certains employés
  • Portée de bloc - comme chaque enclos et chaque laboratoire, avec son propre système d'accès

Comprendre la portée des variables nous permet d'écrire un code mieux organisé, plus sûr et plus prévisible - tout comme une bonne gestion des zones dans un parc rempli de dinosaures dangereux renforce la sécurité de tous.

Dans l'une des prochaines leçons, nous approfondirons le hoisting (remontée), qui est étroitement lié à la portée des variables et influence fortement le fonctionnement du code JavaScript.

Code de cette leçon : index.js
1// Portée des variables - Parc Jurassique
2console.log("Laboratoire de la Portée des Variables");
3console.log("Comprendre la portée (scope) en JavaScript\n");
4
5// ===========================================
6// 1. PORTÉE GLOBALE
7// ===========================================
8console.log("=== 1. Portée globale ===");
9
10const parkName = "Jurassic Park"; // Variable globale
11let totalDinosaurs = 0; // Variable globale
12
13function addDinosaur(name) {
14  totalDinosaurs++; // Accès à la variable globale
15  console.log(`Ajout de ${name}. Nombre total de dinosaures: ${totalDinosaurs}`);
16  console.log(`   Dans le parc: ${parkName}`);
17}
18
19addDinosaur("T-Rex");
20addDinosaur("Velociraptor");
21addDinosaur("Triceratops");
22
23console.log(`\nLe parc ${parkName} a ${totalDinosaurs} dinosaures`);
24
25// ===========================================
26// 2. PORTÉE DE FONCTION
27// ===========================================
28console.log("\n=== 2. Portée de fonction ===");
29
30function feedDinosaur(dinoName) {
31  const foodAmount = 50; // Variable locale de la fonction
32  const message = `Nourrissage de ${dinoName} (portion: ${foodAmount}kg)`;
33
34  console.log(`${message}`);
35  return foodAmount;
36}
37
38feedDinosaur("T-Rex");
39feedDinosaur("Velociraptor");
40
41// console.log(foodAmount); // ERREUR: foodAmount is not defined
42// console.log(message); // ERREUR: message is not defined
43
44// ===========================================
45// 3. PORTÉE DE BLOC (let & const)
46// ===========================================
47console.log("\n=== 3. Portée de bloc (let & const) ===");
48
49function checkSecurity(sector) {
50  console.log(`\nVérification de la sécurité du secteur ${sector}`);
51
52  if (sector === "A") {
53    let dangerLevel = "ÉLEVÉ"; // Variable de bloc
54    const dinosaurType = "T-Rex"; // Variable de bloc
55
56    console.log(`   Niveau de danger: ${dangerLevel}`);
57    console.log(`   Type de dinosaure: ${dinosaurType}`);
58  }
59
60  // console.log(dangerLevel); // ERREUR: dangerLevel is not defined
61  // console.log(dinosaurType); // ERREUR: dinosaurType is not defined
62
63  console.log(`   Vérification du secteur ${sector} terminée`);
64}
65
66checkSecurity("A");
67checkSecurity("B");
68
69// Exemple avec une boucle for
70console.log("\nBoucle avec let:");
71for (let i = 0; i < 3; i++) {
72  console.log(`  Itération ${i + 1}`);
73}
74// console.log(i); // ERREUR: i is not defined
75
76// ===========================================
77// 4. var vs let vs const
78// ===========================================
79console.log("\n=== 4. Différences: var vs let vs const ===");
80
81function demonstrateScope() {
82  console.log("\nDémonstration des portées:");
83
84  // var - portée de fonction (ancienne méthode)
85  if (true) {
86    var dinoVar = "T-Rex (var)";
87    let dinoLet = "Velociraptor (let)";
88    const dinoConst = "Triceratops (const)";
89
90    console.log(`  Dans le bloc - var: ${dinoVar}`);
91    console.log(`  Dans le bloc - let: ${dinoLet}`);
92    console.log(`  Dans le bloc - const: ${dinoConst}`);
93  }
94
95  console.log(`\n  En dehors du bloc - var: ${dinoVar}`); // Fonctionne !
96  // console.log(`  En dehors du bloc - let: ${dinoLet}`); // ERREUR
97  // console.log(`  En dehors du bloc - const: ${dinoConst}`); // ERREUR
98}
99
100demonstrateScope();
101
102// ===========================================
103// 5. CLOSURE
104// ===========================================
105console.log("\n=== 5. Closures ===");
106
107function createDinosaurCounter(startCount = 0) {
108  let count = startCount; // Variable privée
109
110  return {
111    add: function(name) {
112      count++;
113      console.log(`Ajout de ${name}. Compteur: ${count}`);
114    },
115    remove: function(name) {
116      if (count > 0) {
117        count--;
118        console.log(`Retrait de ${name}. Compteur: ${count}`);
119      }
120    },
121    getCount: function() {
122      return count;
123    }
124  };
125}
126
127const sectorA = createDinosaurCounter(5);
128const sectorB = createDinosaurCounter(0);
129
130console.log("\nSecteur A:");
131sectorA.add("T-Rex");
132sectorA.add("Velociraptor");
133console.log(`Total dans le secteur A: ${sectorA.getCount()}`);
134
135console.log("\nSecteur B:");
136sectorB.add("Triceratops");
137console.log(`Total dans le secteur B: ${sectorB.getCount()}`);
138
139// ===========================================
140// 6. FONCTIONS IMBRIQUÉES
141// ===========================================
142console.log("\n=== 6. Fonctions imbriquées et portée ===");
143
144function managePark() {
145  const parkName = "Isla Nublar";
146  let visitors = 1000;
147
148  function openPark() {
149    console.log(`\n${parkName} ouvert pour ${visitors} visiteurs`);
150
151    function welcomeVisitors() {
152      visitors += 50;
153      console.log(`   Accueil de nouveaux visiteurs. Maintenant: ${visitors}`);
154    }
155
156    welcomeVisitors();
157  }
158
159  function closePark() {
160    console.log(`\nFermeture de ${parkName}`);
161    console.log(`   Visiteurs d'aujourd'hui: ${visitors}`);
162  }
163
164  openPark();
165  closePark();
166}
167
168managePark();
169
170// ===========================================
171// 7. SHADOWING (MASQUAGE)
172// ===========================================
173console.log("\n=== 7. Shadowing (masquage de variables) ===");
174
175const dinosaur = "T-Rex (global)";
176
177function checkDinosaur() {
178  const dinosaur = "Velociraptor (fonction)"; // Masque la variable globale
179  console.log(`Dans la fonction: ${dinosaur}`);
180
181  if (true) {
182    const dinosaur = "Triceratops (bloc)"; // Masque celle de la fonction
183    console.log(`   Dans le bloc: ${dinosaur}`);
184  }
185
186  console.log(`   Après le bloc: ${dinosaur}`);
187}
188
189console.log(`Globalement: ${dinosaur}`);
190checkDinosaur();
191console.log(`À nouveau globalement: ${dinosaur}`);
192
193// ===========================================
194// 8. LEXICAL SCOPE (PORTÉE LEXICALE)
195// ===========================================
196console.log("\n=== 8. Portée lexicale ===");
197
198const habitat = "Forêt tropicale";
199
200function outerFunction() {
201  const temperature = 28;
202
203  function innerFunction() {
204    const humidity = 80;
205
206    // Accès à toutes les variables des portées parentes
207    console.log(`Environnement: ${habitat}`);
208    console.log(`   Température: ${temperature}°C`);
209    console.log(`   Humidité: ${humidity}%`);
210  }
211
212  innerFunction();
213}
214
215outerFunction();
216
217// ===========================================
218// 9. EXEMPLE PRATIQUE - SYSTÈME D'ALIMENTATION
219// ===========================================
220console.log("\n=== 9. Système d'alimentation - exemple pratique ===");
221
222function createFeedingSystem() {
223  const feedingSchedule = [];
224  let lastFeedingTime = null;
225
226  return {
227    scheduleFeed: function(dinoName, time) {
228      const entry = { dino: dinoName, time: time, completed: false };
229      feedingSchedule.push(entry);
230      console.log(`Repas programmé: ${dinoName} à ${time}`);
231    },
232
233    completeFeed: function(dinoName) {
234      const entry = feedingSchedule.find(e => e.dino === dinoName && !e.completed);
235      if (entry) {
236        entry.completed = true;
237        lastFeedingTime = new Date().toLocaleTimeString();
238        console.log(`${dinoName} nourri à ${lastFeedingTime}`);
239      } else {
240        console.log(`Aucune alimentation programmée pour ${dinoName}`);
241      }
242    },
243
244    getReport: function() {
245      console.log("\nRAPPORT D'ALIMENTATION:");
246      console.log(`   Dernier repas: ${lastFeedingTime || "Aucun"}`);
247      console.log(`   Repas programmés: ${feedingSchedule.length}`);
248
249      const pending = feedingSchedule.filter(e => !e.completed);
250      if (pending.length > 0) {
251        console.log("\n   En attente:");
252        pending.forEach(e => {
253          console.log(`     - ${e.dino} à ${e.time}`);
254        });
255      }
256    }
257  };
258}
259
260const feedingSystem = createFeedingSystem();
261
262feedingSystem.scheduleFeed("T-Rex", "08:00");
263feedingSystem.scheduleFeed("Velociraptor", "10:00");
264feedingSystem.scheduleFeed("Triceratops", "12:00");
265
266feedingSystem.completeFeed("T-Rex");
267feedingSystem.completeFeed("Velociraptor");
268
269feedingSystem.getReport();
270
271// ===========================================
272// 10. BONNES PRATIQUES
273// ===========================================
274console.log("\n=== 10. Bonnes pratiques ===");
275
276// BON: Utilise const pour les valeurs qui ne changent pas
277const MAX_DINOSAURS = 50;
278console.log(`Nombre maximal de dinosaures: ${MAX_DINOSAURS}`);
279
280// BON: Utilise let pour les valeurs qui changent
281let currentDinoCount = 15;
282currentDinoCount += 5;
283console.log(`Nombre actuel: ${currentDinoCount}`);
284
285// MAUVAIS: Évite var (ancienne méthode)
286// var oldStyle = "Non recommandé";
287
288// BON: Limite la portée des variables au minimum
289function goodScope() {
290  const onlyHere = "Disponible uniquement ici";
291  return onlyHere;
292}
293
294console.log("\nFélicitations ! Tu maîtrises maintenant la portée des variables !");

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quelle déclaration de variable est la plus adaptée pour une valeur constante d'espèce de dinosaure ?

  2. 2. Que va retourner le code suivant : String(65000000) ?

  3. 3. Le Dr Wu organise les données au laboratoire. Quelle association donnée-type JavaScript est INCORRECTE ?

Tâches pratiques dans le jeu

  • Éditeur de code

    Les données d'un formulaire sont toujours du texte : const inputWeight = '6200', const inputLength = '9.5' et const inputTeeth = '800'. Convertis-les en nombres : numWeight avec Number(), numLength avec parseFloat() et numTeeth avec parseInt(). Ensuite, enregistre numWeight de nouveau sous forme de texte dans weightText avec String(). Affiche les quatre valeurs dans la console avec leur type (typeof).

Articles utiles