Getters et Setters en JavaScript

Mosh Hamedani

Follow

Dec 29, 2019 – 5 min de lecture

.

Le concept de getters et setters est assez commun parmi les langages populaires utilisés aujourd’hui. Avez-vous déjà eu besoin de vous assurer qu’une action donnée est toujours exécutée avant ou après l’attribution d’une valeur à la propriété d’un objet ? C’est possible avec les setters. Vous pouvez également effectuer tout type de traitement lors de la récupération de la valeur d’une propriété en utilisant des getters (par exemple, le formatage). Une façon d’implémenter les getters et setters est d’utiliser des méthodes, comme c’est le cas en Java. Cependant, depuis ES5, nous disposons d’une alternative beaucoup plus élégante et pratique en utilisant la syntaxe get et set. Eh bien, commençons!

En JavaScript, les objets sont des collections de propriétés et vous les avez probablement déjà utilisés pour stocker des données. Une propriété est simplement une paire clé-valeur. Voici un exemple :

const options = {
timeout: 5000,
retries: 3,
ip: '192.168.1.20',
port: 4001,
};

Les propriétés d’un objet peuvent être facilement définies et lues, comme ceci :

artist.name = 'Carice Anouk van Houten';console.log(artist.name); //=> "Carice Anouk van Houten"

Encore, ce n’est certainement rien de nouveau si vous avez déjà une certaine expérience de JavaScript. Pour faire une distinction entre ces propriétés régulières et l’autre type que nous verrons dans cet article, nous pouvons appeler les premières « propriétés de données ».

Getters and setters : the old way

Avant ES5, la seule façon que nous avions de mettre en œuvre des getters et setters était d’utiliser des méthodes régulières. Comme dans l’exemple ci-dessous :

J’ai conservé le mot-clé function dans l’exemple ci-dessus pour bien faire comprendre qu’il n’y a pas de magie ici. Seulement des méthodes normales. Nous aurions pu obtenir le même effet en utilisant la syntaxe de définition de méthode de l’ES2015, qui est plus courte et un peu plus élégante:

const config = {
_port: 4001,
setPort(port) {
// ...
},
getPort() {
// ...
},
};

L’utilisation de ces types de getters et setters est assez simple :

config.setPort(8080);
console.log(config.getPort()); //=> 8080

L’incrémentation d’une valeur se ferait comme ceci :

item.setQuantity(item.getQuantity() + 1);

Ce qui semble vraiment verbeux par rapport à l’incrémentation directe d’une propriété :

item.quantity += 1;
// Or even simpler...
item.quantity++;

Getters et setters : pourquoi ?

Dans les langages OO comme Java, C++ ou C#, il est possible d’exposer les membres d’une classe à différents niveaux en utilisant des modificateurs d’accès (comme public, protected et private). Cela sert à mettre en œuvre un concept important de la POO appelé le masquage de données.

Une utilisation très courante des getters et setters dans ces langages est d’exposer les membres d’une classe d’une manière sûre. Par exemple, vous pouvez implémenter uniquement un getter pour vous assurer qu’un membre privé ne sera jamais modifié depuis l’extérieur de la classe. Un setter, à son tour, peut être utilisé pour valider les valeurs fournies et préserver l’intégrité des instances de cette classe.

Qu’en est-il de JavaScript ?

En JavaScript, les choses sont un peu différentes. Au moment de la rédaction de cet article, il n’existe pas de modificateurs d’accès en JS. Actuellement, la meilleure option que nous avons est d’utiliser des symboles, qui nous donnent un certain niveau de confidentialité lorsqu’ils sont utilisés comme clés. Certaines personnes ne les aiment pas, cependant. Surtout parce qu’il est facile de briser cette confidentialité en utilisant la réflexion.

Je ne considère pas que ce soit un vrai problème puisque les langages qui ont la réflexion permettent généralement aux programmeurs de briser l’encapsulation d’une manière ou d’une autre. Le problème que je vois dans les symboles est qu’ils ne sont pas si pratiques à utiliser comme le serait un simple accesseur privé. La bonne nouvelle est qu’une proposition d’EcmaScript qui inclut des champs privés est déjà en phase 3. Et ils seront immunisés contre toute sorte de réflexion.

Dans l’exemple de la section précédente, nous n’avons pas utilisé de symboles ou toute autre astuce pour simuler un membre privé. La propriété _port n’a rien de spécial en soi. C’est juste une propriété de données régulière et en tant que telle, elle peut être définie ou lue directement, en contournant complètement le getter et le setter que nous avons créés.

Puisque l’explication des symboles et d’autres techniques d’encapsulation n’est pas le but de cet article, je n’implémente pas les propriétés privées dans ses exemples de code. Gardez simplement à l’esprit que les getters et setters sont couramment (mais pas toujours) utilisés pour fournir un accès aux membres encapsulés. Enfin, notez le trait de soulignement qui précède le nom de la propriété _port. C’est une convention de fait parmi les développeurs JS, indiquant qu’une propriété donnée est privée et ne devrait pas être accessible depuis l’extérieur de la classe où elle est définie.

Getters and setters : la nouvelle façon avec les propriétés accesseurs

Les propriétés accesseurs sont la façon moderne de définir les getters et setters. Lorsqu’il s’agit de leur définition, elles ne sont pas si différentes de notre exemple précédent, mais c’est leur utilisation qui est vraiment différente. Tout d’abord, adaptons notre code pour utiliser les propriétés d’accès :

Comme vous pouvez le voir, seules deux choses ont changé dans cet exemple :

  • Au lieu d’avoir des méthodes setPort et getPort. Nous utilisons la syntaxe set et get ainsi qu’un seul nom pour la propriété (« port« , dans cet exemple)
  • Nous n’avons pas besoin du mot-clé function ici. En fait, si vous essayez de l’utiliser, vous obtiendrez une SyntaxError.

Comment utiliser les propriétés d’accès ?

Si la définition d’une propriété d’accès est assez similaire à la façon dont nous créons les getters et setters de la vieille école, leur utilisation n’a pas de différence visible avec la façon dont nous utilisons les propriétés de données régulières :

config.port = 8080;
console.log(config.port); //=> 8080

Et voici à quoi ressemble une expression d’incrémentation :

timer.seconds += 1;

Oui. C’est aussi simple que cela. =)

Conclusion

  • Les objets sont des collections de propriétés
  • Une propriété régulière est juste une paire clé-valeur et peut être appelée une « propriété de données »
  • Vous pouvez implémenter des getters et setters comme des méthodes normales. C’est la façon « old school » de le faire en JavaScript.
  • Les getters et setters sont normalement utilisés pour fournir un accès aux membres privés d’une classe.
  • Les propriétés accesseurs peuvent se comporter exactement comme les getters et setters basés sur les anciennes méthodes régulières, mais leur utilisation est conçue pour les faire ressembler à des propriétés de données.

Vous voulez maîtriser JavaScript ? Je recommande vivement les cours de JavaScript de Mosh.

Et si vous avez aimé cet article, partagez-le également avec d’autres personnes!

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.