Javascript • Système de types • Objet
Introduction
Section intitulée « Introduction »Dans cette série d’articles, nous faisons un focus sur les fonctionnalités de base de Javascript.
Cet article concerne le système de types proposé par Javascript.
Nous allons détailler maintenant le type object.
Système de types en Javascript
Section intitulée « Système de types en Javascript »Typage dynamique
Section intitulée « Typage dynamique »Javascript possède un typage dynamique. Qu’est-ce-que cela signifie exactement ?
🔑 Nous ne déclarons pas le type d’une variable avant de l’utiliser.
🔑 Le type d’une variable est déterminé à l’exécution (et pas à la compilation).
🔑 Le type d’une variable peut changer pendant sa durée de vie.
// toto est une chaine de caractères (string)let toto = "text";
// toto est maintenant un nombre (number)toto = 69;
// toto est maintenant un booléen (boolean)toto = true;Typage faible
Section intitulée « Typage faible »Javascript est également faiblement typé. Il permet ainsi des conversions implicites de type.
const oneTwoThree = 123; // numberconst fourFive = "45"; // stringconst result = oneTwoThree + fourFive; // stringconsole.log(result); // ← "12345"Les types Objet
Section intitulée « Les types Objet »Le typage Javascript est divisé en deux mondes : les types de valeurs primitives (ou types primitifs) et les types objet. Les types Objet regroupent :
- le type objet (Object) ;
- le type tableau (Array) ;
- le type fonction (Function) ;
- le type class (Class).
Les types objet sont des types référence (reference type) : une variable d’un type object contient la référence à la valeur. Nous pouvons aussi dire qu’elle pointe vers cette valeur.
Les variables d’un type objet sont muables (mutable ) : nous pouvons changer la valeur d’un objet après sa création, contrairement aux valeurs primitives.
Nous allons maintenant nous concentrer dans cet article sur le type object.
Type object
Section intitulée « Type object »Le type object permet de stocker une collection de paires de clef-valeur (key-value pairs).
Le mot « propriété » est souvent utilisé pour désigner la paire clef-valeur.
La clef est nécessairement de type string ou symbol et doit être unique au sein d’un objet.
La valeur peut être de n’importe quel type (type primitif ou type objet).
// Objet fighterconst fighter = { // Clef = "firstName" - Valeur = "Rocky" firstName: "Rocky",
// Clef = "lastName" - Valeur = "Balboa" lastName: "Balboa",
// Clef = "age" - Valeur = 33 age: 33};La plupart des objets héritent de Object. Ils accèdent ainsi aux méthodes d’instance, par exemple hasOwnProperty() ou valueOf().
Valeur d’une propriété
Section intitulée « Valeur d’une propriété »Opérateur .
Section intitulée « Opérateur . »La façon la plus simple d’accéder à la valeur d’une propriété est d’utiliser l’opérateur de chainage ..
Dans ce cas, la clef à droite de . doit être valide.
const fighter = { firstName: "Rocky", lastName: "Balboa", age: 33};console.log(fighter.firstName); // ← "Rocky"console.log(fighter.gender); // ← undefinedIndexeur []
Section intitulée « Indexeur [] »Nous pouvons également utiliser l’indexeur [].
La valeur entre [ et ] peut être une valeur littérale ou une variable de type string.
const fighter = { firstName: "Rocky", lastName: "Balboa", age: 33};
const key = "lastName";
console.log(fighter["firstName"]); // ← "Rocky"console.log(fighter[key]); // ← "Balboa"console.log(fighter["gender"]); // ← undefinedExistence d’une propriété
Section intitulée « Existence d’une propriété »Opérateur in
Section intitulée « Opérateur in »La façon la plus simple de vérifier la présence (ou l’absence) d’une propriété dans un objet
est d’utiliser l’opérateur in.
const fighter = { firstName: "Rocky", lastName: "Balboa", age: 33};
console.log("firstName" in fighter); // ← true
const key = "lastName";console.log(key in fighter); // ← true
console.log("gender" in fighter); // ← falseMéthode Object.hasOwn()
Section intitulée « Méthode Object.hasOwn() »Nous pouvons également utiliser la méthode statique Object.hasOwn() pour vérifier l’existence d’une propriété.
const fighter = { firstName: "Rocky", lastName: "Balboa", age: 33};
console.log(Object.hasOwn(fighter, "firstName")); // ← true
const key = "lastName";console.log(Object.hasOwn(fighter, key)); // ← true
console.log(Object.hasOwn(fighter, "gender")); // ← falseMéthode hasOwnProperty()
Section intitulée « Méthode hasOwnProperty() »Nous pouvons aussi utiliser la méthode d’instance Object.prototype.hasOwnProperty() pour vérifier l’existence d’une propriété.
const fighter = { firstName: "Rocky", lastName: "Balboa", age: 33};
console.log(fighter.hasOwnProperty("firstName")); // ← true
const key = "lastName";console.log(fighter.hasOwnProperty(key)); // ← true
console.log(fighter.hasOwnProperty("gender")); // ← falseItération
Section intitulée « Itération »Instruction for...in
Section intitulée « Instruction for...in »Nous pouvons parcourir toutes les clefs des propriétés d’un objet en utilisant l’instruction for…in.
const fighter = { firstName: "Rocky", lastName: "Balboa", age: 33};
// ← "firstName" → "Rocky"// ← "lastName" → "Balboa"// ← "age" → 33for (const propertyKey in fighter) { console.log(`${propertyKey} → ${fighter[propertyKey]}`);}Méthode Object.entries()
Section intitulée « Méthode Object.entries() »Nous pouvons également utiliser la méthode statique
Object.entries().
Cette méthode retourne un tableau de toutes les propriétés de l’objet passé en paramètre,
chaque élément étant lui-même un tableau [clef, valeur].
const fighter = { firstName: "Rocky", lastName: "Balboa", age: 33};
// ← "firstName" → "Rocky"// ← "lastName" → "Balboa"// ← "age" → 33for (const [propertyKey, propertyValue] of Object.entries(fighter)) { console.log(`${propertyKey} → ${propertyValue}`);}Méthode Object.keys()
Section intitulée « Méthode Object.keys() »La méthode statique Object.keys() retourne un tableau des clefs des propriétés de l’objet passé en paramètre.
const fighter = { firstName: "Rocky", lastName: "Balboa", age: 33};
// ← "firstName"// ← "lastName"// ← "age"for (const key of Object.keys(fighter)) { console.log(key);}Méthode Object.values()
Section intitulée « Méthode Object.values() »La méthode statique Object.values() retourne un tableau des valeurs des propriétés de l’objet passé en paramètre.
const fighter = { firstName: "Rocky", lastName: "Balboa", age: 33};
// ← "Rocky"// ← "Balboa"// ← 33for (const value of Object.values(fighter)) { console.log(value);}Copie superficielle
Section intitulée « Copie superficielle »Spread operator
Section intitulée « Spread operator »Nous pouvons effectuer une copie superficielle grace au spread operator (…).
const presidentDeGaulle = { firstName: "Charles", lastName: "De Gaulle", gender: "male", address: { houseNumber: 55, street: "rue du Faubourg-Saint-Honoré", zipCode: "75008", city: "Paris", country: "France" }};
const presidentPompidou = { ...presidentDeGaulle, firstName: "Georges", lastName: "Pompidou", nextPresident: true};
// ← Object {// address: Object { houseNumber: 55, street: "rue du Faubourg-Saint-Honoré", … }// firstName: "Georges",// gender: "male",// lastName: "Pompidou",// nextPresident: true// }console.log(presidentPompidou);
console.log(presidentDeGaulle.address === presidentPompidou.address); // ← true...presidentDeGaulleretourne la liste des propriétés de l’objetpresidentDeGaulle:firstName: "Charles",lastName: "De Gaulle",gender: "male",address: { houseNumber: 55, street: "rue du Faubourg-Saint-Honoré", zipCode: "75008", … };- la propriété
firstName: "Georges"remplacefirstName: "Charles"; - la propriété
lastName: "Pompidou"remplacelastName: "De Gaulle"; - la propriété
nextPresident: trueest créée ; - ces propriétés constituent le nouvel objet
presidentPompidou.
Les propriétés presidentDeGaulle.address et presidentPompidou.address sont strictement identiques.
Elles partagent la même référence.
Ainsi si nous modifions l’une, l’autre le sera également.
C’est pour cela que nous parlons de copie superficielle :
- les propriétés avec une valeur primitive sont effectivement dupliquées ;
- les propriétés avec une valeur objet ont leur référence copiée.
Méthode Object.assign()
Section intitulée « Méthode Object.assign() »La méthode statique Object.assign() nous permet également de faire une copie superficielle d’un objet.
const address = { houseNumber: 29, street: "rue de Rivoli", zipCode: "75004", city: "Paris", country: "France"};
const administrativeArea = { department: "Paris", region: "Île-de-France", country: "France"};
const coordinates = { latitude: 48.85676140144051, longitude: 2.352542244281719};
const cityHallOfParis = { name: "Hôtel de ville"};
Object.assign(cityHallOfParis, address, administrativeArea, coordinates);
// ← Object {// name: "Hôtel de ville",// houseNumber: 29,// street: "rue de Rivoli",// zipCode: "75004",// city: "Paris",// country: "France",// department: "Paris",// region: "Île-de-France",// latitude: 48.85676140144051,// longitude: 2.352542244281719// }console.log(cityHallOfParis);Le premier argument de Object.assign() est l’objet cible.
Les arguments suivants sont les objets dont les propriétés seront copiées dans l’objet cible.
Copie profonde
Section intitulée « Copie profonde »La copie profonde d’un objet est une copie complète de toutes les propriétés et sous-propriétés, qu’elles soient des valeurs primitives ou des valeurs objet.
Même si nous pouvons réaliser une copie profonde nous même, en utilisant le spread operator par exemple, cela peut devenir vite compliqué s’il y a beaucoup d’objets imbriqués.
Javascript ne propose pas de fonction pour réaliser de copie profonde.
Sérialisation/Désérialisation
Section intitulée « Sérialisation/Désérialisation »Nous pouvons utiliser la sérialisation JSON.stringify() et dé-sérialisation JSON.parse(). Il faut néanmoins que l’objet à copier puisse être sérialisé.
const receipe = { name: "Flan pâtissier", ingredients: [ { what: "lait", howMuch: { quantity: 1, unit: "litre" } }, { what: "sucre", howMuch: { quantity: 120, unit: "gramme" } }, { what: "farine", howMuch: { quantity: 80, unit: "gramme" } }, { what: "oeufs", howMuch: { quantity: 4 } } ], baking: { where: "four", howLong: { duration: 30, unit: "min" } }};
const copyOfReceipe = JSON.parse(JSON.stringify(receipe));
// ← Object { name: "Flan pâtissier", ingredients: (4) […], baking: {…} }console.log(copyOfReceipe);Fonction structuredClone()
Section intitulée « Fonction structuredClone() »Les navigateurs proposent la fonction structuredClone() via l’objet global window. Cette fonction a les mêmes limitations : il faut que l’objet à copier soit sérialisable. Cette fonction n’est pas disponible dans tous les environnements d’exécution Javascript.
Conclusion
Section intitulée « Conclusion »Nous avons maintenant une vue d’ensemble du type object.
Ce type est la base de nombreux types que nous allons détailler par la suite.
Dans l’article suivant, nous allons détailler les types de collection proposés par Javascript.