Cours JavaScript et TypeScript · Module 1: Bases de JavaScript
Précedence des opérateurs
Dans cette leçon7
À Jurassic Park, les protocoles de sécurité doivent être strictement suivis et exécutés dans le bon ordre. Par exemple, avant d'ouvrir la grille de l'enclos du Tyrannosaurus, tu dois t'assurer que toutes les autres portes sont fermées et que les employés sont dans des zones sûres. L'ordre de ces actions est crucial.
De même en JavaScript, les opérateurs ont leur précédence, qui détermine l'ordre de leur exécution dans les expressions. Comprendre cette hiérarchie est essentiel pour créer des expressions correctes et prévisibles.
Qu'est-ce que la précédence des opérateurs ?
La précédence des opérateurs est une règle qui détermine l'ordre dans lequel les opérateurs sont exécutés dans des expressions complexes. Les opérateurs ayant une précédence plus élevée sont exécutés avant les opérateurs ayant une précédence plus faible.
Imagine qu'à Jurassic Park nous avons une liste de tâches avec différentes priorités :
- Priorité la plus élevée : Vérifier l'alimentation électrique des clôtures
- Priorité moyenne : Vérifier les réserves de nourriture pour les dinosaures
- Priorité faible : Mettre à jour les informations pour les visiteurs
De même, JavaScript a sa propre hiérarchie de précédence des opérateurs.
Tableau de précédence des opérateurs
Voici un tableau simplifié de la précédence des opérateurs en JavaScript, de la plus élevée à la plus faible :
| Précédence | Catégorie | Opérateurs |
|---|---|---|
| 19 | Groupement | ( ... ) |
| 18 | Accès aux propriétés et éléments de tableau | . [] ?. |
| 17 | Appel de fonction | ... ( ... ) |
| 16 | Opérateurs postfixés | ++ -- |
| 15 | Opérateurs préfixés | ! ~ + - ++ -- typeof void delete |
| 14 | Exponentiation | ** |
| 13 | Multiplication, division, modulo | * / % |
| 12 | Addition, soustraction | + - |
| 11 | Décalage de bits | << >> >>> |
| 10 | Comparaisons (inégalités) | < > <= >= instanceof in |
| 9 | Égalité | == != === !== |
| 8 | ET binaire | & |
| 7 | OU exclusif binaire | ^ |
| 6 | OU binaire | | |
| 5 | ET logique | && |
| 4 | OU logique | || |
| 3 | Coalescence des nuls | ?? |
| 2 | Opérateur conditionnel | ? : |
| 1 | Affectation | = += -= *= /= %= <<= >>= >>>= &= ^= |= **= |
| 0 | Opérateur virgule | , |
Exemples de Jurassic Park
Voyons comment la précédence des opérateurs fonctionne en pratique, à l'aide d'exemples du travail quotidien à Jurassic Park :
Exemple 1 : Opérations arithmétiques
1// Calculer la quantité de nourriture nécessaire pour les dinosaures
2
3let smallCarnivores = 5;
4let mediumCarnivores = 3;
5let largeCarnivores = 2;
6
7let dailyConsumptionSmall = 50; // kg
8let dailyConsumptionMedium = 150; // kg
9let dailyConsumptionLarge = 300; // kg
10
11// Sans parenthèses - la précédence des opérateurs détermine l'ordre
12let totalFood = smallCarnivores * dailyConsumptionSmall + mediumCarnivores * dailyConsumptionMedium + largeCarnivores * dailyConsumptionLarge;
13
14console.log(totalFood); // 1300 kg
15
16// La multiplication (*) a une précédence plus élevée que l'addition (+), donc l'expression ci-dessus équivaut à :
17let totalFood2 = (smallCarnivores * dailyConsumptionSmall) + (mediumCarnivores * dailyConsumptionMedium) + (largeCarnivores * dailyConsumptionLarge);
18
19console.log(totalFood2); // 1300 kg (même résultat)Exemple 2 : Opérateurs logiques et de comparaison
1// Vérifier les conditions d'ouverture d'un enclos aux visiteurs
2
3let airTemperature = 28; // degrés Celsius
4let humidity = 60; // pourcentage
5let windSpeed = 15; // km/h
6let threatLevel = 2; // échelle 1-5
7let availableStaff = 5; // nombre d'employés
8let requiredStaff = 3; // nombre minimum
9
10// Condition complexe sans parenthèses
11let openEnclosure = airTemperature > 20 && humidity < 80 && windSpeed < 20 || threatLevel <= 2 && availableStaff >= requiredStaff;
12
13// Comment JavaScript interprète-t-il cela ? L'opérateur && a une précédence plus élevée que ||
14// L'expression ci-dessus équivaut à :
15let openEnclosure2 = ((airTemperature > 20 && humidity < 80 && windSpeed < 20) || (threatLevel <= 2 && availableStaff >= requiredStaff));
16
17console.log(openEnclosure); // true
18console.log(openEnclosure2); // true (même résultat)Exemple 3 : Opérateur conditionnel et affectation
1// Déterminer le statut de sécurité pour différentes espèces de dinosaures
2
3let species = "Velociraptor";
4let aggression = 4; // échelle 1-5
5let fenceHeight = 5; // mètres
6
7// Expression complexe avec opérateur conditionnel et affectation
8let securityStatus = species === "Tyrannosaurus" || species === "Spinosaurus" || aggression >= 4 ? "High" : aggression >= 3 ? "Medium" : "Low";
9
10console.log(securityStatus); // "High" (pour un Velociraptor avec une agression de 4)
11
12// Version plus lisible avec parenthèses montrant l'ordre d'évaluation réel :
13let securityStatus2 = (species === "Tyrannosaurus" || species === "Spinosaurus" || aggression >= 4) ? "High" : (aggression >= 3 ? "Medium" : "Low");
14
15console.log(securityStatus2); // "High" (même résultat)Exemple 4 : Groupement (précédence la plus élevée)
1// Calculer la population estimée de dinosaures après plusieurs générations
2
3let initialPopulation = 2;
4let reproductionRate = 3; // nombre moyen de descendants
5let generations = 2;
6
7// Calcul sans parenthèses
8let estimatedPopulation1 = initialPopulation * reproductionRate ** generations;
9console.log(estimatedPopulation1); // 18 (2 * 3^2 = 2 * 9 = 18)
10
11// Changer l'ordre à l'aide de parenthèses (groupement)
12let estimatedPopulation2 = (initialPopulation * reproductionRate) ** generations;
13console.log(estimatedPopulation2); // 36 ((2 * 3)^2 = 6^2 = 36)Exemple 5 : Combiner différents opérateurs
1// Calculateur de réserves après livraison
2
3let currentResources = 500; // kg
4let weeklyDelivery = 200; // kg
5let averageDailyConsumption = 50; // kg
6let daysInWeek = 7;
7let refrigeratorsWorking = true;
8let maxStorageCapacity = 1000; // kg
9
10// Calculateur complexe sans groupement explicite
11let newState = currentResources + weeklyDelivery - averageDailyConsumption * daysInWeek * (refrigeratorsWorking ? 1 : 1.5);
12
13console.log(newState); // 350 kg (500 + 200 - 50 * 7 * 1)
14
15// Version plus lisible avec parenthèses montrant l'ordre d'évaluation réel :
16let newState2 = currentResources + weeklyDelivery - (averageDailyConsumption * daysInWeek * (refrigeratorsWorking ? 1 : 1.5));
17
18console.log(newState2); // 350 kg (même résultat)
19
20// Vérifier si le nouvel état dépasse la capacité de stockage
21let percentageState = newState / maxStorageCapacity * 100;
22console.log(percentageState + "%"); // 35%Recommandations pour l'utilisation des parenthèses
Bien que JavaScript ait une précédence des opérateurs strictement définie, utiliser des parenthèses pour définir explicitement l'ordre des opérations présente plusieurs avantages :
Augmente la lisibilité du code - même si tu connais la précédence des opérateurs, des parenthèses explicites rendent le code plus lisible pour toi et pour les autres.
Prévient les erreurs - dans les expressions complexes, il est facile de faire des erreurs liées à l'ordre des opérations.
Facilite la modification - si tu modifies plus tard une expression, les parenthèses peuvent prévenir des changements inattendus dans la logique.
1// Exemple d'utilisation de parenthèses pour une meilleure lisibilité
2
3// Moins lisible :
4let isSafe = !fenceBroken && powerActive || emergencyMode && evacuationComplete;
5
6// Plus lisible avec parenthèses :
7let isSafe2 = (!fenceBroken && powerActive) || (emergencyMode && evacuationComplete);Associativité des opérateurs
Outre la précédence, une caractéristique importante des opérateurs est leur associativité, qui détermine l'ordre d'exécution des opérateurs de même précédence :
- Associativité de gauche à droite : la plupart des opérateurs, p. ex.
+,-,*,/ - Associativité de droite à gauche : certains opérateurs, p. ex.
=,**,+=, les opérateurs unaires (!,++,--)
1// Exemple d'associativité de gauche à droite
2let a = 5 - 3 - 2; // (5 - 3) - 2 = 0
3
4// Exemple d'associativité de droite à gauche
5let b = 2;
6let c = 3;
7let d = 4;
8let e = b = c = d; // b = (c = (d)) = 4
9console.log(b, c, d, e); // 4, 4, 4, 4
10
11// L'exponentiation est aussi associative de droite à gauche
12let f = 2 ** 3 ** 2; // 2 ** (3 ** 2) = 2 ** 9 = 512
13let g = (2 ** 3) ** 2; // 8 ** 2 = 64
14console.log(f, g); // 512, 64Conseils pratiques de Jurassic Park
À Jurassic Park, l'ambiguïté dans les protocoles de sécurité peut mener à des conséquences catastrophiques. De même, des expressions ambiguës dans le code peuvent mener à des résultats inattendus. Voici quelques conseils :
Utilise des parenthèses lorsque tu combines différents types d'opérateurs - surtout lorsque tu mélanges des opérateurs arithmétiques, logiques et conditionnels.
Décompose les expressions complexes en expressions plus simples - pour une meilleure lisibilité et un débogage plus facile, tu peux assigner les résultats intermédiaires à des variables.
1// Au lieu de :
2let result = a * b + c * d && e > f || g <= h;
3
4// Mieux :
5let part1 = a * b + c * d;
6let part2 = e > f;
7let part3 = g <= h;
8let result = part1 && part2 || part3;- Sois prudent avec les opérateurs postfixés et préfixés - les opérateurs
++et--peuvent mener à des résultats inattendus lorsqu'ils sont utilisés dans des expressions complexes.
1let dinosaurCount = 5;
2let newCount = dinosaurCount++ * 2; // utilise d'abord la valeur 5, puis incrémente dinosaurCount à 6
3console.log(newCount, dinosaurCount); // 10, 6
4
5let cageCount = 5;
6let newCageCount = ++cageCount * 2; // incrémente d'abord cageCount à 6, puis utilise cette valeur
7console.log(newCageCount, cageCount); // 12, 6Résumé
La précédence des opérateurs en JavaScript, tout comme la hiérarchie des tâches à Jurassic Park, détermine l'ordre des opérations. La connaissance de cette hiérarchie est cruciale pour écrire du code correct et prévisible.
Les choses les plus importantes à retenir :
- Le groupement avec des parenthèses a la précédence la plus élevée et permet de contrôler l'ordre des opérations.
- Les opérateurs arithmétiques (
*,/) ont une précédence plus élevée que (+,-). - Les opérateurs de comparaison (
>,<,>=,<=) ont une précédence plus élevée que les opérateurs d'égalité (==,===,!=,!==). - Le ET logique (
&&) a une précédence plus élevée que le OU (||). - Les opérateurs d'affectation (
=,+=,-=, etc.) ont l'une des précédences les plus faibles.
Souviens-toi, en cas de doute, il vaut toujours mieux utiliser des parenthèses pour plus de clarté - tout comme à Jurassic Park, où il vaut mieux trop se protéger contre des situations inattendues que de risquer des conséquences imprévues.
Dans la prochaine leçon, nous examinerons les structures de contrôle - les instructions conditionnelles qui permettent de prendre des décisions basées sur des conditions précises - essentielles pour gérer une entreprise aussi complexe que Jurassic Park.
Code de cette leçon : index.js
1// Priorité des opérateurs en JavaScript
2// Ordre des opérations
3
4// === Priorité arithmétique ===
5console.log("=== Priorité arithmétique ===");
6
7// La multiplication avant l'addition
8console.log("2 + 3 * 4 =", 2 + 3 * 4); // 14 (pas 20 !)
9console.log("(2 + 3) * 4 =", (2 + 3) * 4); // 20 (les parenthèses changent l'ordre)
10
11// L'exponentiation a une priorité plus élevée que la multiplication
12console.log("2 * 3 ** 2 =", 2 * 3 ** 2); // 18 (pas 36 !)
13console.log("(2 * 3) ** 2 =", (2 * 3) ** 2); // 36
14
15// === Priorité logique ===
16console.log("\n=== Priorité logique ===");
17
18// ET (&&) a une priorité plus élevée que OU (||)
19let a = true, b = false, c = true;
20console.log("true || false && false:", true || false && false); // true
21// Équivalent : true || (false && false) -> true || false -> true
22
23console.log("(true || false) && false:", (true || false) && false); // false
24
25// === Comparaison et logique ===
26console.log("\n=== Combinaison comparaison et logique ===");
27
28let age = 25;
29let weight = 7000;
30let diet = "carnivore";
31
32// Sans parenthèses - peut prêter à confusion
33let dangerous = diet === "carnivore" && weight > 5000 || age > 30;
34console.log("Sans parenthèses:", dangerous);
35
36// Avec parenthèses - clair et lisible
37let dangerousClear = (diet === "carnivore" && weight > 5000) || age > 30;
38console.log("Avec parenthèses:", dangerousClear);
39
40// === Opérateur conditionnel (ternaire) ===
41console.log("\n=== Opérateur conditionnel ===");
42let status = weight > 5000 ? "Grand dinosaure" : "Petit dinosaure";
43console.log("Statut:", status);
44
45// Ta mission :
46// 1. Calcule des expressions avec différentes priorités
47// 2. Utilise des parenthèses pour changer l'ordre des opérations
48// 3. Utilise l'opérateur conditionnel (ternaire)
49Tu 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. Quel opérateur logique a la priorité la plus élevée en JavaScript ?
2. Comment peux-tu forcer un ordre des opérations différent de l'ordre par défaut en JavaScript ?
Tâches pratiques dans le jeu
- Tri vertical
Classe les catégories d'opérateurs de la priorité la plus élevée à la plus faible :