Fonctionnalités supplémentaires des classes en JavaScript

Fonctionnalités supplémentaires des classes en JavaScript

Dans cet article, nous expliquerons les fonctionnalités supplémentaires des classes en JavaScript.

YouTube Video

Fonctionnalités supplémentaires des classes en JavaScript

Propriétés privées en JavaScript

En JavaScript, les propriétés privées sont des propriétés accessibles uniquement à l'intérieur de l'objet ou de la classe. Cela permet un design de code plus sécurisé et robuste en offrant une encapsulation, rendant impossible la modification ou la référence directe depuis un code externe.

Introduit dans ECMAScript 2020 (ES11) en 2020, l'utilisation de # (dièse) pour définir des champs privés dans une classe a été introduite. Cela offre une méthode plus claire, remplaçant les conventions privées traditionnelles de JavaScript (comme les noms de variables commençant par un tiret bas).

Avantages des propriétés privées

Voici les avantages des propriétés privées.

  • Encapsulation : Masque l'état interne de l'extérieur et maintient la cohérence des données.
  • Sécurité : Empêche les propriétés d'être modifiées accidentellement par un code externe.
  • Meilleure Maintenabilité : Masque l'implémentation des objets ou des classes et clarifie l'interface exposée à l'extérieur.

Comment utiliser les propriétés privées

Définir des propriétés privées dans les classes

Les champs privés sont définis à l'aide d'un nom commençant par #. Ce champ ne peut pas être directement accessible depuis les instances de la classe ou de ses sous-classes.

 1class Person {
 2    // Define private property
 3    #name;
 4
 5    constructor(name) {
 6        this.#name = name;
 7    }
 8
 9    // Method to access the private property
10    getName() {
11        return this.#name;
12    }
13
14    // Method to change the private property
15    setName(newName) {
16        this.#name = newName;
17    }
18}
19
20const john = new Person("John");
21console.log(john.getName()); // John
22
23// Cannot access private property directly
24console.log(john.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class

Dans le code ci-dessus, #name est une propriété privée qui ne peut pas être directement accessible depuis l'extérieur de la classe Person. Vous ne pouvez accéder ou modifier le nom qu'à travers les méthodes getName et setName.

Définir des méthodes privées

Comme les propriétés privées, les méthodes privées sont également définies avec un nom commençant par #. Les méthodes privées ne peuvent être appelées qu'à l'intérieur de la classe.

 1class Counter {
 2    #count = 0;
 3
 4    increment() {
 5        this.#count++;
 6        this.#logCount(); // Calling private method
 7    }
 8
 9    // Private method
10    #logCount() {
11        console.log(`Current count: ${this.#count}`);
12    }
13}
14
15const counter = new Counter();
16counter.increment(); // Current count: 1
17
18// Cannot access private method directly
19counter.#logCount(); // SyntaxError: Private field '#logCount' must be declared in an enclosing class

Ici, #logCount est défini comme une méthode privée et ne peut pas être accessible depuis l'extérieur de la classe. Cette méthode est uniquement utilisée à l'intérieur de la classe.

Avantages et considérations des propriétés privées

Avantage

  • Comme il ne peut pas être accédé directement depuis l'extérieur de la classe, les modifications ou opérations non intentionnelles sont évitées.
  • Comme les parties non visibles depuis l'extérieur peuvent être bien cachées, vous pouvez gérer clairement les parties que vous exposez comme API.

Notes

  • Étant donné que les champs privés sont complètement cachés de l'extérieur de la classe, les tests et le débogage peuvent devenir difficiles. Par conséquent, il est important de fournir une API pouvant être rigoureusement testée dès l'étape de conception.
  • Les champs privés se comportent différemment des autres parties de JavaScript avec des caractéristiques basées sur des prototypes car ils sont uniques pour chaque instance.

Implémentation pseudonyme traditionnelle des propriétés privées

Avant l'introduction des champs privés utilisant #, JavaScript ne disposait pas d'une syntaxe officielle pour les propriétés privées. Par conséquent, dans le passé, les propriétés pseudo-privées étaient implémentées de la manière suivante.

Convention consistant à utiliser des underscores

Les développeurs indiquaient conventionnellement 'privé' en préfixant les noms des variables avec un underscore.

 1class Car {
 2    constructor(brand) {
 3        this._brand = brand; // Using an underscore to indicate private
 4    }
 5
 6    getBrand() {
 7        return this._brand;
 8    }
 9}
10
11const car = new Car("Toyota");
12console.log(car.getBrand()); // Toyota
13console.log(car._brand); // Toyota (Accessible from outside)

Cette méthode est simplement une 'convention', et en pratique, les propriétés peuvent encore être accessibles depuis l'extérieur.

Implémentation des propriétés privées à l'aide des closures

Il est également possible de réaliser des propriétés privées en utilisant des closures avec une portée de fonction.

 1function createPerson(name) {
 2    let _name = name; // Private variable within function scope
 3
 4    return {
 5        getName: function() {
 6            return _name;
 7        },
 8        setName: function(newName) {
 9            _name = newName;
10        }
11    };
12}
13
14const person = createPerson("Alice");
15console.log(person.getName()); // Alice
16person.setName("Bob");
17console.log(person.getName()); // Bob
18
19// Cannot access directly from outside
20console.log(person._name); // undefined

Avec cette méthode, la variable _name est enfermée dans la portée de la fonction et ne peut pas être directement accessible depuis l'extérieur.

Résumé

Les propriétés privées en JavaScript sont très efficaces pour fournir une encapsulation dans la conception des classes et des objets, contribuant à protéger les données en toute sécurité. La notation # pour les champs privés introduite dans ES2020 offre une méthode de gestion de la confidentialité plus claire et plus sécurisée par rapport aux conventions traditionnelles et closures.

Chaînage optionnel en JavaScript

Le chaînage optionnel est une syntaxe très utile en JavaScript pour accéder aux propriétés des objets profondément imbriqués. Il améliore la lisibilité et la maintenabilité du code en permettant un accès sûr sans avoir à vérifier individuellement l'existence de propriétés spécifiques.

Syntaxe de base du chaînage optionnel

Le chaînage optionnel peut être utilisé en plaçant ? avant le point (.) ou la notation entre crochets utilisée pour accéder à une propriété. Cette notation renvoie undefined lorsqu'une propriété traversée est null ou undefined, permettant au programme de continuer à s'exécuter sans générer d'erreur.

Exemple :

 1const user = {
 2    name: 'John',
 3    address: {
 4        street: '123 Main St',
 5        city: 'New York'
 6    }
 7};
 8
 9// Without using optional chaining
10const city = user && user.address && user.address.city;
11console.log(city);  // New York
12
13// Using optional chaining
14const cityWithOptionalChaining = user?.address?.city;
15console.log(cityWithOptionalChaining);  // New York

Dans cet exemple, nous accédons à l'address et à sa propriété city de l'objet user. Sans utiliser l'opérateur de chaînage optionnel, vous devrez effectuer plusieurs vérifications d'existence, mais avec celui-ci, vous pouvez accéder en toute sécurité à la propriété en une seule instruction.

Utilisation du chaînage optionnel avec des tableaux et des fonctions

Le chaînage optionnel est applicable non seulement aux propriétés des objets, mais aussi aux éléments des tableaux et aux appels de fonctions.

Exemple avec des tableaux :

1const users = [{ name: 'Alice' }, { name: 'Bob' }];
2
3// Accessing the non-existent third element
4const thirdUser = users[2]?.name;
5console.log(thirdUser);  // undefined

Exemple avec des fonctions :

 1const user = {
 2    greet: function() {
 3        return 'Hello!';
 4    }
 5};
 6
 7// Call the function only if greet exists
 8const greeting = user.greet?.();
 9console.log(greeting);  // Hello!
10
11// Return undefined if greet does not exist
12const nonExistentGreeting = user.nonExistentMethod?.();
13console.log(nonExistentGreeting);  // undefined

Combiner le chaînage optionnel avec des valeurs par défaut

Lors de l'utilisation du chaînage optionnel, il est courant d'utiliser l'opérateur logique OU (||) ou l'opérateur de fusion null (??) pour spécifier des valeurs par défaut si une propriété n'existe pas.

Exemple :

 1const user = {
 2    name: 'John',
 3    address: {
 4        city: 'New York'
 5    }
 6};
 7
 8// Set a default value for a non-existent property
 9const state = user?.address?.state || 'Unknown';
10console.log(state);  // Unknown
11
12// Example using the nullish coalescing operator
13const zipCode = user?.address?.zipCode ?? '00000';
14console.log(zipCode);  // 00000

L'opérateur || considère false, 0, '', etc., comme des valeurs fausses, tandis que l'opérateur ?? utilise la valeur par défaut uniquement si l'opérande est null ou undefined.

Avantages du chaînage optionnel

  • Accès sûr aux objets imbriqués : En utilisant le chaînage optionnel, vous n'avez plus besoin d'effectuer des vérifications explicites d'existence, rendant le code plus concis.
  • Évite les erreurs : Il peut éviter les erreurs d'exécution même si une propriété est null ou undefined.
  • Lisibilité et maintenabilité améliorées : Surtout lorsque vous travaillez avec de nombreux objets imbriqués, la lisibilité du code est grandement améliorée.

Précautions avec le chaînage optionnel

  • L'utilisation fréquente du chaînage optionnel peut être le signe que la conception de la structure des données est excessivement complexe. Vous devriez viser un modèle de données simple.
  • Étant donné que certains anciens navigateurs et moteurs JavaScript ne le supportent pas, vous devrez peut-être utiliser des polyfills ou des transpileurs.

Conclusion

Le chaînage optionnel est une fonctionnalité puissante qui simplifie l'accès sécurisé aux propriétés et aux fonctions des objets imbriqués en JavaScript. Il est particulièrement efficace pour accéder à des structures de données profondément imbriquées, contribuant ainsi à éviter les erreurs et à améliorer la lisibilité du code.

Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.

YouTube Video