W3docs

Membres privés et protégés des classes JavaScript

Découvrez les membres privés (#) et la convention _ pour les membres protégés dans les classes JavaScript, avec getters, setters et bonnes pratiques.

Une classe a souvent besoin de masquer une partie de son fonctionnement interne pour que le code extérieur ne puisse pas lire ou modifier ces éléments directement. Cette page présente les deux façons dont JavaScript permet de le faire : les membres véritablement privés déclarés avec le préfixe #, et la convention du tiret bas _ que les développeurs utilisent pour marquer des membres comme « protégés » (destinés uniquement à la classe et à ses sous-classes).

Vous découvrirez quand utiliser chacune de ces approches, pourquoi les champs # sont réellement inaccessibles depuis l'extérieur, et comment combiner des champs privés avec des getters et setters pour exposer une interface contrôlée et validée. Si les classes sont nouvelles pour vous, commencez d'abord par le chapitre Syntaxe de base des classes.

Introduction à l'encapsulation en JavaScript

L'encapsulation est un principe fondamental de la programmation orientée objet (POO) : elle regroupe les données (variables) et les méthodes (fonctions) qui opèrent sur ces données en une seule unité — un objet — et contrôle l'accès aux éléments internes de cet objet. L'objectif est d'exposer une interface publique petite et délibérée tout en cachant les détails d'implémentation derrière elle.

Pourquoi est-ce important ? Lorsque l'état interne est masqué, le code extérieur ne peut pas mettre votre objet dans un état invalide, et vous êtes libre de modifier le fonctionnement interne de la classe sans casser le code qui l'utilise. En JavaScript, l'encapsulation est obtenue avec des champs et méthodes privés #. JavaScript n'a pas de modificateur protected natif, les développeurs le simulent donc avec une convention de nommage (le préfixe _), comme expliqué ci-dessous.

Propriétés et méthodes privées

Un membre privé de classe est déclaré avec le préfixe # dans son nom. Il ne peut être accédé que depuis l'intérieur du corps de la classe — toute tentative de le lire ou de l'écrire depuis l'extérieur provoque une erreur de syntaxe stricte, et non simplement undefined. Il s'agit d'une véritable confidentialité appliquée par le langage.

Un champ doit être déclaré dans le corps de la classe avant de pouvoir être utilisé (vous ne pouvez pas créer un champ # à la volée dans le constructeur comme vous le feriez avec une propriété publique). Notez également que les champs privés # sont non-énumérables : ils n'apparaissent pas dans Object.keys(), for...in, ni dans la sortie de JSON.stringify().

javascript— editable

Pourquoi # est véritablement privé

Contrairement à la convention du tiret bas, un champ # est invisible en dehors de la classe. Vous ne pouvez pas y accéder via user.#name, par accès entre crochets comme user["#name"], ni via Object.keys(). La première forme est une erreur de syntaxe ; les autres ne trouvent tout simplement pas le champ.

javascript— editable

Méthodes privées

Les méthodes peuvent également être privées : préfixez le nom de la méthode avec #. Une méthode privée est utile pour les fonctions utilitaires internes que les appelants ne devraient jamais invoquer directement — par exemple, une logique de validation ou de formatage qui prend en charge l'API publique sans en faire partie.

javascript— editable

Propriétés et méthodes protégées (la convention _)

JavaScript ne possède pas de mot-clé protected. Par convention, un membre destiné à être utilisé par la classe et ses sous-classes — mais pas par le code extérieur — est préfixé par un seul tiret bas _. Il s'agit purement d'un signal à l'attention des autres développeurs ; un membre _ reste entièrement lisible et modifiable depuis n'importe où. Utilisez-le lorsque les sous-classes ont besoin d'y accéder (un champ # n'est pas accessible depuis les sous-classes), et acceptez que la protection repose sur un accord, non sur une contrainte.

javascript— editable

Comme les membres _ sont hérités comme n'importe quelle propriété normale, une sous-classe peut s'appuyer sur eux. C'est la raison pratique d'utiliser la convention plutôt que # lorsqu'on conçoit pour l'héritage :

javascript— editable

Encapsulation par accesseurs : bonnes pratiques

Lorsque vous intégrez des propriétés et méthodes privées et protégées dans vos projets JavaScript, tenez compte des bonnes pratiques suivantes pour maximiser leurs avantages :

  • Utilisez des champs privés pour les données sensibles ou invariantes : Stockez tout ce qui ne doit pas être touché directement — compteurs internes, valeurs mises en cache, état brut — sous la forme d'un champ #. Cela garantit l'intégrité et prévient les effets secondaires non souhaités.
  • Tirez parti des getters et setters : Gardez le champ privé et exposez-le via un getter et setter. Le setter est l'occasion de valider ou de transformer l'entrée avant qu'elle n'atteigne le champ privé, de sorte que l'objet ne puisse jamais contenir une valeur invalide.

Dans l'exemple ci-dessous, #age ne peut être modifié qu'à travers le setter, qui rejette les valeurs négatives :

javascript— editable

Vous pouvez également exposer un état en lecture seule en définissant un getter sans setter correspondant — le consommateur peut lire la valeur mais n'a aucun moyen d'écraser le champ privé sous-jacent.

  • Appliquez les membres protégés pour l'héritage : Utilisez des propriétés et méthodes protégées lorsque vous souhaitez qu'elles soient accessibles dans les sous-classes. Cette stratégie favorise une structure plus flexible et hiérarchique dans vos applications.

Techniques et patterns avancés

Au-delà des bases, JavaScript permet des patterns et techniques sophistiqués pour encapsuler et structurer votre code de manière plus efficace :

  • Pattern module : Utilisez les fermetures (closures) et les expressions de fonction immédiatement invoquées (IIFE) pour créer des portées privées.
  • Fonctions factory : Ces fonctions retournent de nouveaux objets, permettant de disposer de données privées grâce aux fermetures, sans avoir besoin du mot-clé new.
  • Proxies : Les Proxies JavaScript peuvent être utilisés pour créer des enveloppes de protection autour des objets, en contrôlant l'accès à leurs propriétés et méthodes.

Conclusion

Utilisez les champs et méthodes # lorsque vous souhaitez une confidentialité réelle et appliquée qu'aucun code extérieur ne peut atteindre. Utilisez la convention du tiret bas _ lorsque les sous-classes ont besoin d'un accès et que la protection peut reposer sur un accord. Combinez les champs privés avec des getters et setters pour exposer une interface contrôlée et validée — et des getters en lecture seule lorsque l'état doit être observable mais non modifiable.

Sujets connexes

Pratique

Pratique
Quelles affirmations sur les propriétés et méthodes privées et protégées en JavaScript sont vraies ?
Quelles affirmations sur les propriétés et méthodes privées et protégées en JavaScript sont vraies ?
Was this page helpful?