--- title: Utiliser les objets slug: Web/JavaScript/Guide/Working_with_Objects tags: - Beginner - Comparing object - Document - Guide - JavaScript - Object - l10n:priority translation_of: Web/JavaScript/Guide/Working_with_Objects original_slug: Web/JavaScript/Guide/Utiliser_les_objets --- {{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Keyed_collections", "Web/JavaScript/Guide/Details_of_the_Object_Model")}} JavaScript est conçu autour d'un paradigme simple, basé sur les objets. Un objet est un ensemble de propriétés et une propriété est une association entre un nom (aussi appelé _clé_) et une valeur. La valeur d'une propriété peut être une fonction, auquel cas la propriété peut être appelée « méthode ». En plus des objets natifs fournis par l'environnement, il est possible de construire ses propres objets. Ce chapitre aborde la manipulation d'objets, l'utilisation des propriétés, fonctions et méthodes, il explique également comment créer ses objets. ## Un aperçu des objets À l'instar de nombreux autres langages de programmation, on peut comparer les objets JavaScript aux objets du monde réel. En JavaScript, un objet est une entité à part entière qui possède des propriétés et un type. Si on effectue cette comparaison avec une tasse par exemple, on pourra dire qu'une tasse est un objet avec des propriétés. Ces propriétés pourront être la couleur, la forme, le poids, le matériau qui la constitue, etc. De la même façon, un objet JavaScript possède des propriétés, chacune définissant une caractéristique. ## Les objets et les propriétés Un objet JavaScript possède donc plusieurs propriétés qui lui sont associées. Une propriété peut être vue comme une variable attachée à l'objet. Les propriétés d'un objet sont des variables tout ce qu'il y a de plus classiques, exception faite qu'elles sont attachées à des objets. Les propriétés d'un objet représentent ses caractéristiques et on peut y accéder avec une notation utilisant le point « . », de la façon suivante : ```js nomObjet.nomPropriete ``` Comme pour les variables JavaScript en général, le nom de l'objet (qui peut être une variable) et le nom des propriétés sont sensibles à la casse (une lettre minuscule ne sera pas équivalente à une lettre majuscule). On peut définir une propriété en lui affectant une valeur. Ainsi, si on crée un objet `maVoiture` et qu'on lui donne les propriétés `fabricant`, `modèle`, et `année` : ```js let maVoiture = new Object(); maVoiture.fabricant = "Ford"; maVoiture.modele = "Mustang"; maVoiture.annee = 1969; ``` L'exemple précédent peut également s'écrire avec **[la syntaxe littérale pour initialiser les objets](#object_initializers)** : on fournit une liste, délimitée par des virgules, qui contient des paires de noms et de valeurs décrivant les propriétés et où le tout est encadré d'accolades (`{}`) : ```js let maVoiture = { make: 'Ford', model: 'Mustang', year: 1969 }; ``` Les propriétés d'un objet qui n'ont pas été affectées auront la valeur [`undefined`](/fr/docs/Web/JavaScript/Reference/Global_Objects/undefined) (et non [`null`](/fr/docs/Web/JavaScript/Reference/Global_Objects/null)). ```js maVoiture.color; // undefined ``` On peut aussi définir ou accéder à des propriétés JavaScript en utilisant une notation avec les crochets (voir la page sur [les accesseurs de propriétés](/fr/docs/Web/JavaScript/Reference/Operators/Property_Accessors) pour plus de détails). Les objets sont parfois appelés « tableaux associatifs ». Cela peut se comprendre, car chaque propriété est associée avec une chaîne de caractères qui permet d'y accéder. Ainsi, par exemple, on peut accéder aux propriétés de l'objet `maVoiture` de la façon suivante : ```js maVoiture["fabricant"] = "Ford"; maVoiture["modèle"] = "Mustang"; maVoiture["année"] = 1969; ``` Le nom d'une propriété d'un objet peut être n'importe quelle chaîne JavaScript valide (ou n'importe quelle valeur qui puisse être convertie en une chaîne de caractères), y compris la chaîne vide. Cependant, n'importe quel nom de propriété qui n'est pas un identifiant valide (par exemple si le nom d'une propriété contient un tiret, un espace ou débute par un chiffre) devra être utilisé avec la notation à crochets. Cette notation s'avère également utile quand les noms des propriétés sont déterminés de façon dynamique (c'est-à-dire qu'on ne sait pas le nom de la propriété avant l'exécution). Par exemple : ```js // on crée quatre variables avec une même instruction let monObj = new Object(); let str = "maChaîne"; let rand = Math.random(); let obj = new Object(); monObj.type = "Syntaxe point"; monObj["date created"] = "Chaîne avec un espace"; monObj[str] = "Une valeur qui est une chaîne"; monObj[rand] = "Nombre aléatoire"; monObj[obj] = "Objet"; monObj[""] = "Une chaîne vide"; console.log(monObj); ``` On notera que les valeurs utilisées entre les crochets sont automatiquement converties en chaînes de caractères grâce à la méthode [`toString()`](/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/toString) sauf si ces valeurs sont des symboles (cf. [`Symbol`](/fr/docs/Web/JavaScript/Reference/Global_Objects/Symbol)). En effet, les noms des propriétés pour les objets JavaScript peuvent être des chaînes de caractères ou des symboles. Ainsi, dans l'exemple précédent, lorsqu'on ajoute la clé `obj` sur `monObj`, le moteur JavaScript appelle la méthode `obj.toString()` et utilise la chaîne de caractères renvoyée par cette méthode comme nom pour la propriété. On peut également accéder aux propriétés d'un objet en utilisant une valeur qui est une chaîne de caractères enregistrée dans une variable : ```js let nomPropriété = "fabricant"; maVoiture[nomPropriété] = "Ford"; nomPropriété = "modèle"; maVoiture[nomPropriété] = "Mustang"; ``` La notation avec les crochets peut être utilisée dans une boucle [`for...in`](/fr/docs/Web/JavaScript/Reference/Statements/for...in) afin de parcourir les propriétés énumérables d'un objet. Pour illustrer comment cela fonctionne, on définit la fonction suivante qui affiche les propriétés d'un objet qu'on lui a passé en argument avec le nom associé : ```js function afficherProps(obj, nomObjet) { let resultat = ""; for (let i in obj) { if (obj.hasOwnProperty(i)) { resultat += `${nomObjet}.${i} = ${obj[i]}\n`; } } return resultat; } ``` Si on appelle la fonction avec `afficherProps(maVoiture, "maVoiture")`, cela affichera le contenu suivant dans la console : ```js maVoiture.fabricant = Ford maVoiture.modele = Mustang maVoiture.annee = 1969 ``` ## Lister les propriétés d'un objet À partir d'ECMAScript 5, il existe trois méthodes natives pour lister/parcourir les propriétés d'un objet : - Les boucles [`for...in`](/fr/docs/Web/JavaScript/Reference/Statements/for...in) qui permettent de parcourir l'ensemble des propriétés énumérables d'un objet et de sa chaîne de prototypes. - [`Object.keys(o)`](/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) qui permet de renvoyer un tableau contenant les noms (clés ou _keys_) des propriétés propres (celles qui ne sont pas héritées via la chaîne de prototypes) d'un objet `o` pour les propriétés énumérables. - [`Object.getOwnPropertyNames(o)`](/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames) qui permet de renvoyer un tableau contenant les noms des propriétés propres (énumérables ou non) d'un objet `o`. Avant ECMAScript 5, il n'existait aucune méthode native pour lister l'ensemble des propriétés d'un objet. Cependant, on pouvait utiliser le code suivant pour y parvenir : ```js function listerToutesLesProprietes(o){ let objectToInspect; let resultat = []; for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)){ resultat = resultat.concat(Object.getOwnPropertyNames(objectToInspect)); } return resultat; } ``` Cela peut être utile pour révéler les propriétés « cachées » où leur nom est réutilisé dans la chaîne de prototypes. Pour lister les propriétés accessibles, il suffit de retirer les duplicatas du tableau. ## Créer de nouveaux objets Un environnement JavaScript possède certains objets natifs prédéfinis. En plus de ces objets, il est possible de créer ses propres objets. Pour cela, on peut utiliser un [initialisateur d'objet](/fr/docs/Web/JavaScript/Reference/Operators/Object_initializer). On peut aussi créer un constructeur puis instancier un objet avec cette fonction en utilisant l'opérateur `new`. ### Utiliser les initialisateurs d'objets On peut créer des objets avec une fonction qui est un constructeur, mais on peut aussi créer des objets avec des [initialisateurs d'objets](/fr/docs/Web/JavaScript/Reference/Operators/Object_initializer). On appelle parfois cette syntaxe la notation _littérale_. La syntaxe utilisée avec les initialisateurs d'objets est la suivante : ```js let obj = { propriete_1: valeur_1, // propriete_# peut être un identifiant 2: valeur_2, // ou un nombre // ..., "propriete n": valeur_n }; // ou une chaîne ``` où on a `obj` le nom de l'objet qu'on souhaite créer et chaque `propriete_i` un identifiant (que ce soit un nom, un nombre ou une chaîne de caractères) et chaque `valeur_i` une expression dont la valeur sera affectée à la propriété `propriete_i`. S'il n'est pas nécessaire d'utiliser l'objet `obj` par la suite, il n'est pas nécessaire de réaliser l'affectation à une variable (attention alors à l'encadrer dans des parenthèses pour que le littéral objet soit bien interprété comme une instruction et non pas comme un bloc.) Les initialisateurs d'objets sont des expressions et chaque initialisateur entraîne la création d'un nouvel objet dans l'instruction pour laquelle il est exécuté. Des initialisateurs d'objets identiques créeront des objets distincts qui ne seront pas équivalents. Les objets sont créés de la même façon qu'avec `new Object()`, les objets créés à partir d'une expression littérale seront des instances d'`Object`. L'instruction suivante crée un objet et l'affecte à une variable `x` si et seulement si l'expression `cond` est vraie : ```js if (cond) let x = {emplacement: "le monde"}; ``` Dans l'exemple suivant, on crée un objet `maHonda` avec trois propriétés. La propriété `moteur` est également un objet avec ses propres propriétés. ```js let maHonda = { couleur: "rouge", roue: 4, moteur: { cylindres: 4, taille: 2.2 } }; ``` De la même façon, on pourra utiliser des initialisateurs pour créer des tableaux. Pour plus d'informations à ce sujet, voir [les littéraux de tableaux](/fr/docs/Web/JavaScript/Guide/Grammar_and_types#les_litt.c3.a9raux_de_tableaux). ### Utiliser les constructeurs On peut aussi créer des objets d'une autre façon, en suivant deux étapes : 1. On définit une fonction qui sera un constructeur définissant le type de l'objet. La convention, pour nommer les constructeurs, est d'utiliser une majuscule comme première lettre pour l'identifiant de la fonction. 2. On crée une instance de l'objet avec `new`. Pour définir le type d'un objet, on crée une fonction qui définit le nom de ce type et les propriétés et méthodes des instances. Ainsi, si on souhaite créer un type d'objet pour représenter des voitures, on pourra nommer ce type `voiture`, et il pourra avoir des propriétés pour le fabricant, le modèle et l'année. Pour ce faire, on pourra écrire la fonction suivante : ```js function Voiture(fabricant, modele, annee) { this.fabricant = fabricant; this.modele = modele; this.annee = annee; } ``` On voit ici qu'on utilise le mot-clé `this` pour affecter des valeurs aux propriétés d'un objet en fonction des valeurs passées en arguments de la fonction. On peut désormais créer un objet `maVoiture` de la façon suivante : ```js let maVoiture = new Voiture("Eagle", "Talon TSi", 1993); ``` Cette instruction crée un objet `maVoiture` et lui affecte les valeurs fournies pour ses propriétés. On obtient donc `maVoiture.fabricant` qui sera la chaîne de caractères "Eagle", `maVoiture.annee` qui sera l'entier 1993, et ainsi de suite. Grâce à ce constructeur, on peut ensuite créer autant d'objets `Voiture` que nécessaire. Par exemple : ```js let voitureMorgan = new Voiture("Audi", "A3", 2005); let voitureMax = new Voiture("Mazda", "Miata", 1990); ``` Un objet peut avoir une propriété qui est elle-même un objet. Ainsi, si on définit un type d'objet `personne` de cette façon : ```js function Personne(nom, age, sexe) { this.nom = nom; this.age = age; this.sexe = sexe; } ``` et qu'on instancie deux nouveaux objets `personne` avec ```js let max = new Personne("Max Gun", 33, "M"); let morgan = new Personne("Morgan Sousbrouille", 39, "M"); ``` On pourra réécrire la fonction de définition pour le type `Voiture` pour inclure une propriété `proprietaire` qui est représentée par un objet `personne` : ```js function Voiture(fabricant, modele, annee, proprietaire) { this.fabricant = fabricant; this.modele = modele; this.annee = annee; this.proprietaire = proprietaire; } ``` Pour instancier des nouveaux objets, on pourra donc utiliser : ```js let voiture1 = new Voiture("Mazda", "Miata", 1993, max); let voiture2 = new Voiture("Audi", "A3", 2005, morgan); ``` On notera que le dernier argument n'est pas une chaîne de caractères ou une valeur numérique mais bien un objet. Les objets `max` et `morgan` sont passés en arguments pour représenter les propriétaires. Ainsi, si on veut obtenir le nom du propriétaire pour `voiture2`, on peut accéder à la propriété de la façon suivante : ```js voiture2.proprietaire.nom ``` Il est toujours possible d'ajouter une propriété à un objet défini précédemment. Par exemple, on peut ajouter une propriété à l'objet `voiture1` avec l'instruction : ```js voiture1.couleur = "noir"; ``` Ici, on ajoute une propriété `couleur` à `voiture1`, et on lui affecte une valeur "noir". Cependant, cela n'affecte pas les autres objets `voiture`. Pour ajouter une nouvelle propriété à tous les objets, il faudra ajouter la propriété au constructeur `voiture`. ### Utiliser la méthode `Object.create()` Les objets peuvent également être créés en utilisant la méthode [`Object.create()`](/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/create). Cette méthode peut s'avérer très utile, car elle permet de choisir le prototype pour l'objet qu'on souhaite créer, sans avoir à définir un constructeur. ```js // Propriétés pour animal et encapsulation des méthodes let Animal = { type: "Invertébrés", // Valeur par défaut value of properties afficherType : function() { // Une méthode pour afficher le type Animal console.log(this.type); } } // On crée un nouveau type d'animal, animal1 let animal1 = Object.create(Animal); animal1.afficherType(); // affichera Invertébrés // On crée un type d'animal "Poisson" let poisson = Object.create(Animal); poisson.type = "Poisson"; poisson.afficherType(); // affichera Poisson ``` ## L'héritage Tous les objets JavaScript héritent d'un autre objet. L'objet dont on hérite est appelé _prototype_ et les propriétés héritées peuvent être accédées via l'objet `prototype` du constructeur. Pour plus d'informations sur le fonctionnement de l'héritage, voir la page sur [l'héritage et la chaîne de prototypes](/fr/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). ## Indexer les propriétés d'un objet Il est possible d'accéder à une propriété via son nom et via son indice (ordinal). Si on définit une propriété grâce à un nom, on accédera toujours à la valeur via le nom. De même, si on définit une propriété grâce à un indice, on y accèdera toujours via son indice. Cette restriction s'applique lorsqu'on crée un objet et ses propriétés via un constructeur et lorsqu'on déclare les propriétés explicitement (par exemple avec `maVoiture.couleur = "rouge"`). Si on définit une propriété d'un objet avec `maVoiture[5] = "25 kmh"`, on pourra faire référence à cette propriété grâce à `maVoiture[5]`. Il existe une exception à cette règle lorsqu'on manipule des objets "semblables à des tableaux" provenant d'API Web telles que l'objet `forms`. Pour ces objets semblables à des tableaux, on peut accéder à une propriété de l'objet grâce à son nom (si l'attribut [`name`](/fr/docs/Web/HTML/Global_attributes#name) est utilisé sur l'élément HTML) ou grâce à son index selon l'ordre dans le document. Ainsi, si on souhaite cibler un élément `