| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Classes/Private_elements | [Back] [Original] |
Get to know MDN better
Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.
Cette fonctionnalit est bien tablie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2021.
Les proprits prives sont les quivalents des proprits de classe normales, qui sont publiques, comme les champs de classe, les mthodes de classe, etc. Les proprits prives sont cres en utilisant un croisillon # comme prfixe et ne peuvent pas tre rfrence lgalement en dehors de la classe. L'encapsulation de cette isolation dans la classe est gre par le moteur JavaScript.
Les proprits prives n'taient pas disponibles de faon native en JavaScript avant l'apparition de cette syntaxe. En utilisant l'hritage prototypal, ce comportement pouvait tre mul avec des objets WeakMap, ou des fermetures (closures), mais cela n'tait pas aussi pratique que la syntaxe avec #.
class ClasseAvecProprietesPrivees {
#champPrive;
#champPriveAvecInitialisateur = 42;
#methodePrivee() {
//
}
static #champPriveStatique;
static #champPriveStatiqueAvecInitialisateur = 42;
static #methodePriveeStatique() {
//
}
}
Des restrictions complmentaires s'appliquent :
#constructor.Pour chaque type de proprit d'une classe, on a des quivalents privs :
Toutes ces fonctionnalits reprsentent des proprits prives. Toutefois, les constructeurs ne peuvent pas tre privs en JavaScript. Pour empcher une classe d'tre construite en dehors d'elle-mme, il faudra utiliser un marqueur priv.
Les proprits prives sont dclares avec des identifiants prfixs par # (en anglais, on parle de hash names). Le prfixe avec le croisillon fait partie inhrente du nom de la proprit (on peut y voir une analogie avec l'ancienne convention utilisant un tiret bas comme prfixe _champPrive, mais il ne s'agit pas d'une proprit dont le nom est une chane de caractre classique et on ne peut donc pas y accder dynamiquement en utilisant la notation avec les crochets).
Les cas suivants sont des erreurs de syntaxe :
delete.class ClasseAvecChampPrive {
#champPrive;
constructor() {;
delete this.#champPrive; // Erreur de syntaxe
this.#champNonDeclare = 42; // Erreur de syntaxe
}
}
const instance = new ClasseAvecChampPrive();
instance.#champPrive; // Erreur de syntaxe
JavaScript est un langage dynamique et peut faire cette vrification la compilation grce la syntaxe particulire des proprits prives.
Note : Le code excut dans la console Google Chrome permet d'accder aux proprits prives en dehors de la classe. Il s'agit d'une drogation propre aux outils de dveloppement.
Si vous tentez d'accder une proprit prive sur un objet qui ne dispose pas de la proprit, vous obtiendrez une exception TypeError et non undefined, comme c'est le cas pour les proprits normales (publiques).
class C {
#x;
static getX(obj) {
return obj.#x;
}
}
console.log(C.getX(new C())); // undefined
console.log(C.getX({})); // TypeError: Cannot read private member #x from an object whose class did not declare it
Cet exemple illustre galement l'accs aux proprits prives depuis les fonctions statiques et pour les instances de la classe dfinies par ailleurs.
L'oprateur in peut tre utilis pour vrifier si un objet tiers possde une proprit prive. L'oprateur renverra true si le champ priv existe, false sinon.
class C {
#x;
constructor(x) {
this.#x = x;
}
static getX(obj) {
if (#x in obj) return obj.#x;
return "obj doit tre une instance de C";
}
}
console.log(C.getX(new C("toto"))); // "toto"
console.log(C.getX(new C(0.196))); // 0.196
console.log(C.getX(new C(new Date()))); // la date/heure courante
console.log(C.getX({})); // "obj doit tre une instance de C"
Un corollaire cette dclaration pralable et cette absence de suppression est que si on trouve un objet possdant au moins une proprit prive de la classe courante (via un try...catch ou une vrification in), cet objet en possdera toutes les autres proprits prives. Un objet possdant une proprit prive d'une classe signifie gnralement qu'il a t construit par cette classe (a n'est pas forcment le cas).
Les proprits prives ne font par partie du modle d'hritage prototypal, car elles ne sont accessibles qu'au sein du corps de la classe courante et ne sont pas hrites par les sous-classes. Les proprits prives qui ont le mme nom, mais des classes diffrentes sont totalement diffrentes et n'ont aucune relation entre elles. Il faut voir les proprits prives comme des mtadonnes externes rattaches chaque instance, gres par la classe. Pour cette raison, Object.freeze() et Object.seal() n'ont pas d'effet sur les proprits prives.
Pour plus d'informations sur la faon dont les champs privs sont initialiss, voir la page sur les champs publics des classes.
Les champs privs regroupent les champs privs des instances et les champs privs statiques. Ils ne sont accessibles qu'au sein de la dclaration de la classe.
l'instar de leurs homologues publics, les champs privs des instances :
super() pour une sous-classeclass ClasseAvecChampPrive {
#champPrive;
constructor() {
this.#champPrive = 42;
}
}
class SousClasse extends ClasseAvecChampPrive {
#champPriveSousClasse;
constructor() {
super();
this.#champPriveSousClasse = 23;
}
}
new SousClasse(); // Dans certains outils de dveloppement, cela affichera SousClasse {#champPrive: 42, #champPriveSousClasse: 23}
Note :
La proprit #champPrive, provenant de la classe de base ClasseAvecChampPrive est prive et est donc uniquement accessible l'intrieur de ClasseAvecChampPrive et est inaccessible depuis SousClasse.
Le constructeur d'une classe peut renvoyer un objet diffrent, qui sera alors utilis comme nouveau this pour le constructeur de la classe drive. La classe drive pourra alors dfinir des champs privs sur l'objet qui a t renvoy, permettant ainsi indirectement d'adjoindre des champs privs pour des objets qui ne sont pas des instances.
class Stamper extends class {
// Une classe de base dont le constructeur renvoie
// l'objet qui lui est fourni.
constructor(obj) {
return obj;
}
} {
// Cette dclaration rajoutera le champ priv
// sur l'objet renvoy par le constructeur
// de la classe de base
#stamp = 42;
static getStamp(obj) {
return obj.#stamp;
}
}
const obj = {};
new Stamper(obj);
// `Stamper` appelle `Base`, qui renvoie `obj`, et `obj` est
// dsormais la valeur `this`. `Stamper` dfinit alors
// `#stamp` sur `obj`
console.log(obj); // Dans certains outils de dveloppement, on verra {#stamp: 42}
console.log(Stamper.getStamp(obj)); // 42
console.log(obj instanceof Stamper); // false
// On ne peut pas ajouter ainsi deux fois des proprits prives
new Stamper(obj); // Error: Initializing an object twice is an error with private fields
Attention :
Implmenter un tel fonctionnement sera source de confusion. Il est gnralement recommand de ne rien renvoyer partir du constructeur, a fortiori, quelque chose qui n'a pas de lien avec this.
l'instar de leurs homologues publics, les champs statiques privs :
class ClasseAvecChampStatiquePrive {
static #champStatiquePrive = 42;
static methodeStatiquePublique() {
return ClasseAvecChampStatiquePrive.#champStatiquePrive;
}
}
console.log(ClasseAvecChampStatiquePrive.methodeStatiquePublique()); // 42
Pour les champs statiques privs, seule la classe qui dfinit le champ statique priv peut accder au champ. Cela peut donner des comportements inattendus lorsque this est utilis. Dans l'exemple suivant, this fait rfrence la classe SousClasse (et non la classe ClasseAvecChampStatiquePrive), et quand on essaie d'appeler SousClasse.methodeStatiquePublique(), cela dclenche une erreur TypeError.
class ClasseAvecChampStatiquePrive {
static #champStatiquePrive = 42;
static methodeStatiquePublique() {
return this.#champStatiquePrive;
}
}
class SousClasse extends ClasseAvecChampStatiquePrive {}
SousClasse.methodeStatiquePublique(); // TypeError: Cannot read private member #champStatiquePrive from an object whose class did not declare it
Le mme comportement se produira si la mthode est appele avec super, car les mthodes appeles avec super ne reoivent pas la classe parente comme valeur pour this.
class ClasseAvecChampStatiquePrive {
static #champStatiquePrive = 42;
static methodeStatiquePublique() {
// Mme appele avec super, `this` fera rfrence
// SousClasse
return this.#champStatiquePrive;
}
}
class SousClasse extends ClasseAvecChampStatiquePrive {
static appelleSuperMethode() {
return super.methodeStatiquePublique();
}
}
SousClasse.appelleSuperMethode(); // TypeError: Cannot read private member #champStatiquePrive from an object whose class did not declare it
Une bonne pratique consiste toujours accder aux champs privs statiques avec le nom de la classe plutt qu'avec this, afin que l'hritage ne casse pas la mthode.
Les mthodes prives incluent les mthodes prives des instances et les mthodes statiques prives. Les mthodes prives sont uniquement accessibles l'intrieur de la dclaration de la classe.
la diffrence de leurs homologues publiques, les mthodes prives des instances :
.prototypeclass ClasseAvecMethodePrivee {
#methodePrivee() {
return 42;
}
methodePublique() {
return this.#methodePrivee();
}
}
const instance = new ClasseAvecMethodePrivee();
console.log(instance.methodePublique()); // 42
Les mthodes prives des instances peuvent tre des gnrateurs, des mthodes asynchrones, des fonctions de gnration asynchrone. Il est aussi possible de crer des accesseurs et mutateurs privs en suivant les mmes rgles de syntaxe que leurs homologues publiques (accesseur et mutateur).
class ClasseAvecAccesseurPrive {
#message;
get #messageDecore() {
return `${this.#message}`;
}
set #messageDecore(msg) {
this.#message = msg;
}
constructor() {
this.#messageDecore = "Coucou le monde";
console.log(this.#messageDecore);
}
}
new ClasseAvecAccesseurPrive(); // Coucou le monde
la diffrence des mthodes publiques, les mthodes prives ne sont pas accessibles sur la proprit .prototype de leur classe.
class C {
#methode() {}
static getMethode(x) {
return x.#methode;
}
}
console.log(C.getMethode(new C())); // [Function: #methode]
console.log(C.getMethode(C.prototype)); // TypeError: Receiver must be an instance of class C
Comme leurs homologues publiques, les mthodes prives statiques :
class ClasseAvecMethodePriveeStatique {
static #methodePriveeStatique() {
return 42;
}
static methodeStatiquePublique() {
return ClasseAvecMethodePriveeStatique.#methodePriveeStatique();
}
}
console.log(ClasseAvecMethodePriveeStatique.methodeStatiquePublique()); // 42
Les mthodes prives statiques peuvent tre des gnrateurs, des fonctions asynchrones, ou des gnrateurs asynchrones.
La mme restriction voque pour les champs statiques privs s'applique et peut mener des comportements inattendus lorsqu'on utilise this. Dans l'exemple suivant, quand on essaie d'appeler SousClasse.methodeStatiquePublique(), this fait rfrence la classe SousClasse (et non la classe ClasseAvecMethodePriveeStatique), ce qui entrane une exception TypeError.
class ClasseAvecMethodePriveeStatique {
static #methodePriveeStatique() {
return 42;
}
static methodeStatiquePublique() {
return this.#methodePriveeStatique();
}
}
class SousClasse extends ClasseAvecMethodePriveeStatique {}
console.log(SousClasse.methodeStatiquePublique()); // TypeError: Cannot read private member #methodePriveeStatique from an object whose class did not declare it
Dans d'autres langages, il est possible d'indiquer un constructeur comme priv, ce qui empche d'instancier la classe en dehors d'elle-mme. Seules des mthodes statiques de construction peuvent tre utilises pour crer des instances, voire il n'est pas possible de crer des instances. JavaScript ne dispose pas d'une syntaxe native pour ce faire, mais on peut y parvenir en utilisant un marqueur statique priv.
class ConstructeurPrive {
static #estUneConstructionInterne = false;
constructor() {
if (!ConstructeurPrive.#estUneConstructionInterne) {
throw new TypeError("ConstructeurPrive n'est pas constructible");
}
ConstructeurPrive.#estUneConstructionInterne = false;
// La suite de la logique d'initialisation
}
static create() {
ConstructeurPrive.#estUneConstructionInterne = true;
const instance = new ConstructeurPrive();
return instance;
}
}
new ConstructeurPrive(); // TypeError: ConstructeurPrive n'est pas constructible
ConstructeurPrive.create(); // ConstructeurPrive {}
| Spcification |
|---|
| ECMAScript 2027 LanguageSpecification # prod-PrivateIdentifier |
classCette page a t modifie le 7 sept. 2025 par les contributeurices du MDN.
Certaines parties de ce contenu sont protges par le droit d'auteur 19982026 des contributeurs individuels de mozilla.org. Contenu disponible sous une licence Creative Commons.
| Web Proxy Viewer | New URL | Original Page |