Cours JavaScript et TypeScript · Module 5: JavaScript avancé

Les objets et les tableaux en JavaScript

8 min de lecture
Dans cette leçon5

À Jurassic Park, on stocke d'énormes quantités de données sur les dinosaures - leurs noms, espèces, âge, état de santé et bien plus encore. Imagine que tu gardes chaque information dans une variable séparée : blueName, blueAge, blueSpecies, puis la même chose pour Charlie et Delta. Au bout d'une semaine, le laboratoire croule sous des éprouvettes sans étiquette. Pour gérer ces données efficacement, on a besoin de deux structures de données fondamentales de JavaScript : les objets et les tableaux.

Ce que tu vas apprendre

  • rassembler les données d'un dinosaure dans un objet, c'est-à-dire une fiche ADN
  • lire, modifier et supprimer des propriétés
  • ajouter des méthodes à la fiche, c'est-à-dire des comportements
  • construire et imbriquer des tableaux
  • reconnaître les motifs : du littéral à la classe

Les objets - fiches ADN de dinosaures

Un objet en JavaScript est une collection de paires clé-valeur qui permet de stocker des données liées en un seul endroit. Imagine un objet comme une fiche d'information sur un dinosaure - elle contient toutes les données pertinentes de façon organisée.

Créer des objets

La façon la plus simple de créer un objet est d'utiliser des accolades {}, c'est-à-dire un littéral d'objet. À l'intérieur, tu écris des paires : la clé, les deux-points et la valeur, séparées par des virgules :

1// Fiche d'information d'un Velociraptor
2const raptor = {
3  name: "Blue",
4  species: "Velociraptor",
5  age: 4,
6  isAlpha: true,
7  dangerLevel: 8
8};
9
10console.log(raptor); // Affiche l'objet entier

Toute la fiche de Blue est maintenant une seule valeur dans une seule constante. L'écriture new Object() existe aussi, mais le littéral est plus court, et c'est lui la norme. Ne confonds pas les parenthèses : les accolades {} créent un objet, et les crochets [] un tableau.

Accéder aux propriétés d'un objet

Il y a deux façons d'accéder aux propriétés d'un objet : la notation par point et la notation par crochets, dans laquelle tu indiques le nom de la clé sous forme de texte :

1// 1. Notation par point (dot notation) - la plus utilisée
2console.log(raptor.name);      // "Blue"
3console.log(raptor.age);       // 4
4
5// 2. Notation par crochets (bracket notation) - utile pour les clés dynamiques
6console.log(raptor["species"]); // "Velociraptor"
7
8const property = "dangerLevel";
9console.log(raptor[property]);  // 8 - utile quand la clé est dans une variable

Les deux chemins mènent à la même valeur. Je te recommande le point au quotidien et les crochets pour les clés stockées dans une variable. L'écriture raptor->name, connue dans d'autres langages, est ici une erreur de syntaxe, et la lecture d'une clé inexistante renvoie simplement undefined.

Modifier et ajouter des propriétés

La fiche d'un dinosaure n'est pas gravée dans la pierre : l'âge augmente, le raptor change d'enclos, et certaines entrées doivent être rayées. Une affectation ou l'opérateur delete suffisent :

1// Modifier une propriété existante
2raptor.age = 5;
3
4// Ajouter une nouvelle propriété
5raptor.habitat = "Enclos A3";
6
7// Supprimer une propriété
8delete raptor.habitat;

Une affectation à une clé existante écrase la valeur, à une nouvelle clé elle ajoute une propriété, et delete la supprime complètement. Qu'est-ce qui n'a pas changé ? raptor désigne toujours le même objet - const interdit seulement de réaffecter la constante, pas de modifier son contenu.

Les méthodes d'un objet

Un objet peut contenir des fonctions comme valeurs - on les appelle des méthodes. Ce sont les comportements du dinosaure, écrits juste à côté de ses données :

1const raptor = {
2  name: "Blue",
3  age: 4,
4  isAlpha: true,
5  skills: ["hunt", "communicate", "lead"],
6
7  // Méthode - une fonction à l'intérieur d'un objet
8  attack() {
9    return this.name + " attaque !";
10  },
11
12  // Une autre méthode utilisant this
13  introduce() {
14    return "Je suis " + this.name + ", âge : " + this.age + ".";
15  }
16};
17
18console.log(raptor.attack());     // "Blue attaque !"
19console.log(raptor.introduce());  // "Je suis Blue, âge : 4."

À l'intérieur d'une méthode, this désigne l'objet sur lequel on l'a appelée, c'est pourquoi raptor.attack() connaît le nom de Blue sans aucun argument. La propriété skills montre au passage qu'une valeur peut être un tableau entier.

Trois façons d'écrire une méthode

Tu peux écrire une méthode de trois façons, et toutes sont du JavaScript valide. Comparons-les sur une même fiche :

1const raptor = {
2  name: "Blue",
3  // 1. Écriture abrégée d'une méthode (ES6)
4  hunt() { return this.name + " chasse"; },
5  // 2. Propriété contenant une expression de fonction
6  communicate: function () { return this.name + " communique"; },
7  // 3. Propriété contenant une fonction fléchée
8  roar: () => "Grrr !"
9};
10
11console.log(raptor.hunt());        // "Blue chasse"
12console.log(raptor.communicate()); // "Blue communique"
13console.log(raptor.roar());        // "Grrr !"

Les deux premières écritures fonctionnent de façon identique. Une fonction fléchée n'a pas son propre this, donc this.name à l'intérieur ne désignera pas le raptor. Je te recommande l'écriture abrégée : c'est la plus courte, et this s'y comporte de façon prévisible.

Les méthodes statiques d'Object

JavaScript fournit plusieurs méthodes utiles pour travailler avec les objets. Tu les appelles sur l'objet global Object, en passant la fiche en argument :

1const dino = { name: "Rex", species: "T-Rex", age: 12 };
2
3// Object.keys() - tableau des clés
4console.log(Object.keys(dino));   // ["name", "species", "age"]
5
6// Object.values() - tableau des valeurs
7console.log(Object.values(dino)); // ["Rex", "T-Rex", 12]
8
9// Object.entries() - tableau de paires [clé, valeur]
10console.log(Object.entries(dino));
11// [["name", "Rex"], ["species", "T-Rex"], ["age", 12]]

Chacune renvoie un nouveau tableau, et l'objet dino reste intact. Les clés te serviront à vérifier les champs de la fiche, et les paires de Object.entries() à parcourir clés et valeurs en même temps.

Les tableaux - listes de dinosaures

Un tableau est une liste ordonnée d'éléments, idéale pour stocker des collections de données du même type.

Créer des tableaux

Tu crées un tableau avec des crochets [], en séparant les éléments par des virgules. Chaque élément a un numéro de position, l'indice, compté à partir de zéro :

1// Tableau de noms de Velociraptors
2const raptors = ["Blue", "Charlie", "Delta", "Echo"];
3
4// Tableau d'objets
5const dinosaurs = [
6  { name: "Blue", species: "Velociraptor", age: 4 },
7  { name: "Rex", species: "T-Rex", age: 12 },
8  { name: "Bronto", species: "Brachiosaurus", age: 8 }
9];
10
11console.log(raptors[0]);        // "Blue" - premier élément (indice 0)
12console.log(raptors.length);    // 4 - nombre d'éléments
13console.log(dinosaurs[1].name); // "Rex" - accès à un objet dans le tableau

Le dernier des quatre raptors a donc l'indice 3, c'est-à-dire length - 1. Une lecture hors limites, par exemple raptors[10], renvoie undefined au lieu d'une erreur. Pour atteindre les champs d'un objet dans un tableau, tu combines l'indice et le point.

Les structures de données complexes

On peut imbriquer les objets et les tableaux pour créer des structures de données complexes - le plan du parc contient des secteurs, et chaque secteur la liste de ses habitants :

1const park = {
2  name: "Jurassic Park",
3  sectors: [
4    {
5      id: "A",
6      name: "Zone des prédateurs",
7      dinosaurs: ["T-Rex", "Velociraptor"]
8    },
9    {
10      id: "B",
11      name: "Zone des herbivores",
12      dinosaurs: ["Brachiosaurus", "Triceratops"]
13    }
14  ]
15};
16
17console.log(park.sectors[0].dinosaurs[1]); // "Velociraptor"

Le chemin park.sectors[0].dinosaurs[1] se lit de gauche à droite : le parc, le premier secteur, sa liste, le deuxième élément. Chaque étape est un simple point ou un simple indice.

De la fiche à la fabrique - les motifs d'objets

Quand les raptors se multiplient, recopier la fiche pour chacun devient vite pénible. Les motifs montent par paliers : l'objet simple, l'objet avec méthodes, la fonction fabrique, la fonction constructeur et la classe. Une fonction fabrique renvoie un nouvel objet à chaque appel :

1function createRaptor(name, age) {
2  return {
3    name,
4    age,
5    attack() {
6      return this.name + " attaque !";
7    }
8  };
9}
10
11const charlie = createRaptor("Charlie", 3);
12console.log(charlie.attack()); // "Charlie attaque !"

L'écriture name, est un raccourci pour name: name. Au-dessus viennent la fonction constructeur appelée avec new, dont les méthodes vont dans un prototype commun, et la classe - une écriture plus moderne du même mécanisme. Tu connais les classes grâce à la location sur la syntaxe ES6, et elles reviendront ici dans le motif Builder.

Tableau ou objet ?

Le choix de la structure commence par l'analyse des données : cherches-tu par ordre ou par nom ? Un troupeau passé en revue dans l'ordre, c'est un tableau, et la description d'un individu avec des caractéristiques nommées, c'est un objet. Ensuite, tu implémentes et tu testes, et tu gardes l'optimisation pour la fin.

Dans le laboratoire ci-dessous t'attendent la fiche de Blue et un plan du parc vide - complète les secteurs selon les commentaires TODO. Dans la prochaine leçon, tu commenceras à gérer le troupeau avec des méthodes de tableaux comme push() et splice().

Retiens bien : un objet est la fiche ADN d'un seul dinosaure, et un tableau est la liste de tout le troupeau.

Code de cette leçon : index.js
1// Objets et tableaux dans Jurassic Park
2
3// === OBJETS ===
4// Cree un objet raptor avec les proprietes : name, species, age, isAlpha, skills (tableau)
5const raptor = {
6  name: "Blue",
7  age: 4,
8  isAlpha: true,
9  skills: ["hunt", "communicate", "lead"],
10
11  // Ajoute une methode attack() qui renvoie : this.name + " attaque !"
12  attack() {
13    return this.name + " attaque !";
14  }
15};
16
17console.log("=== Objet raptor ===");
18console.log("Nom :", raptor.name);
19console.log("Age :", raptor.age);
20console.log("Attaque :", raptor.attack());
21console.log("Premiere competence :", raptor.skills[0]);
22
23// Methodes de Object
24console.log("\n=== Methodes de Object ===");
25console.log("Cles :", Object.keys(raptor));
26console.log("Valeurs :", Object.values(raptor));
27
28// === TABLEAUX ===
29const raptors = ["Blue", "Charlie", "Delta", "Echo"];
30console.log("\n=== Tableau raptors ===");
31console.log("Meute :", raptors);
32console.log("Premier :", raptors[0]);
33console.log("Longueur :", raptors.length);
34
35// === STRUCTURES COMPLEXES ===
36// TODO : cree un objet park avec une propriete sectors (tableau d'objets)
37// Chaque secteur doit avoir : id, name, dinosaurs (tableau)
38const park = {
39  name: "Jurassic Park",
40  sectors: [
41    // TODO : ajoute des secteurs
42  ]
43};
44
45console.log("\n=== Park ===");
46console.log(park);

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. Laquelle des syntaxes suivantes est valide pour créer un objet en JavaScript ?

  2. 2. Lesquelles des façons suivantes d'accéder à une propriété d'objet sont valides ?

Voici 2 des 5 questions de cette leçon. Réponds aux autres dans le jeu.

Tâches pratiques dans le jeu

  • Éditeur de code

    Crée : const raptor = { name: 'Blue', age: 4, isAlpha: true, skills: ['hunt', 'communicate', 'lead'], attack() { return this.name + ' attacks!' } }. Appelle raptor.attack() et raptor.skills[0].

Articles utiles