diff options
Diffstat (limited to 'files/fr/web/javascript/reference/classes/private_class_fields/index.html')
-rw-r--r-- | files/fr/web/javascript/reference/classes/private_class_fields/index.html | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/files/fr/web/javascript/reference/classes/private_class_fields/index.html b/files/fr/web/javascript/reference/classes/private_class_fields/index.html new file mode 100644 index 0000000000..7d5aff7d9c --- /dev/null +++ b/files/fr/web/javascript/reference/classes/private_class_fields/index.html @@ -0,0 +1,207 @@ +--- +title: Variables de classe privés +slug: Web/JavaScript/Reference/Classes/Private_class_fields +tags: + - Classe + - Fonctionnalité du langage + - JavaScript +translation_of: Web/JavaScript/Reference/Classes/Private_class_fields +--- +<div>{{JsSidebar("Classes")}}</div> + +<div>Les propriétés de classe sont publiques par défaut et peuvent être lues et modifiées à l'extérieur de la classe. Cependant, <a href="https://github.com/tc39/proposal-class-fields">une proposition expérimentale</a>, permettant de définir des variables privées dans une classe avec le préfixe <code>#</code>, est disponible.</div> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox notranslate">class ClassWithPrivateField { + #privateField +} + +class ClassWithPrivateMethod { + #privateMethod() { + return 'hello world' + } +} + +class ClassWithPrivateStaticField { + static #PRIVATE_STATIC_FIELD +} +</pre> + +<h2 id="Exemples">Exemples</h2> + +<h3 id="Champs_privés_statiques">Champs privés statiques</h3> + +<p>Les champs privés sont accessibles depuis le constructeur et depuis l'intérieur de la déclaration de la classe elle-même.</p> + +<p>La limitation des variables statiques ne pouvant être appelées que par des méthodes statiques tient toujours.</p> + +<pre class="brush: js notranslate">class ClassWithPrivateStaticField { + static #PRIVATE_STATIC_FIELD + + static publicStaticMethod() { + ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42 + return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD + } +} + +console.assert(ClassWithPrivateStaticField.publicStaticMethod() === 42)</pre> + +<p>Les champs statiques privés sont ajoutés au constructeur de la classe au moment de l'évaluation de classe..</p> + +<p>Il y a une restriction de provenance sur les champs statiques privés. Seule la classe qui a défini un champ statique privé peut y accéder.</p> + +<p>Ceci peut conduire à un comportement inattendu lors de l'utilisation de <strong><code>this</code></strong>.</p> + +<pre class="brush: js notranslate">class BaseClassWithPrivateStaticField { + static #PRIVATE_STATIC_FIELD + + static basePublicStaticMethod() { + this.#PRIVATE_STATIC_FIELD = 42 + return this.#PRIVATE_STATIC_FIELD + } +} + +class SubClass extends BaseClassWithPrivateStaticField { } + +let error = null + +try { + SubClass.basePublicStaticMethod() +} catch(e) { error = e} + +console.assert(error instanceof TypeError) +</pre> + +<h3 id="Champs_dinstance_privés">Champs d'instance privés</h3> + +<p>Les champs d'instance privés sont déclarés avec des <strong>noms</strong> à <strong># </strong>(prononcés "<em>noms à hash</em>", <span class="st">"<em>hash names</em>" en anglais</span>), qui sont des identifieurs préfixés par <code>#</code>. Le <code>#</code> fait partie du nom lui-même. Il est utilisé tant pour la déclaration que pour l'accès.</p> + +<p>L'encapsulation est forcée par le langage. C'est une erreur de syntaxe que de faire référence aux noms à <code>#</code> en dehors de leur portée.</p> + +<pre class="brush: js notranslate">class ClassWithPrivateField { + #privateField + + constructor() { + this.#privateField = 42 + this.#randomField = 666 // Erreur de syntaxe + } +} + +const instance = new ClassWithPrivateField() +instance.#privateField === 42 // Erreur de syntaxe +</pre> + +<h3 id="Méthodes_Privées">Méthodes Privées</h3> + +<h4 id="Méthodes_statiques_privées">Méthodes statiques privées</h4> + +<p>Comme leur équivalents publics, les méthodes statiques privées sont appelées dans la classe elle-même, pas dans les instances de la classe. Comme les champs statiques privés, elles ne sont accessibles que depuis l'intérieur de la déclaration de la classe.</p> + +<p>Les méthodes statiques privées peuvent être des fonctions génératrices, asynchrones et génératrices asynchrones.</p> + +<pre class="brush: js notranslate">class ClassWithPrivateStaticMethod { + static #privateStaticMethod() { + return 42 + } + + static publicStaticMethod1() { + return ClassWithPrivateStaticMethod.#privateStaticMethod(); + } + + static publicStaticMethod2() { + return this.#privateStaticMethod(); + } +} + +console.assert(ClassWithPrivateStaticMethod.publicStaticMethod1() === 42); +console.assert(ClassWithPrivateStaticMethod.publicStaticMethod2() === 42); +</pre> + +<p>Cela peut conduire à un comportement inattendu lors de l'utilisation de <strong><code>this</code></strong>. Dans l'exemple suivant, <code>this</code> fait référence à la classe <code>Derived</code> (pas à la classe <code>Base</code>) lorsqu'on essaie d'appeler <code>Derived.publicStaticMethod2()</code>, et fait ainsi apparaître la même "restriction de provenance" que mentionné ci-dessus :</p> + +<pre class="brush: js notranslate">class Base { + static #privateStaticMethod() { + return 42; + } + static publicStaticMethod1() { + return Base.#privateStaticMethod(); + } + static publicStaticMethod2() { + return this.#privateStaticMethod(); + } +} + +class Derived extends Base {} + +console.log(Derived.publicStaticMethod1()); // 42 +console.log(Derived.publicStaticMethod2()); // TypeError +</pre> + +<h4 id="Méthodes_dinstance_privées">Méthodes d'instance privées</h4> + +<p>Les méthodes d'instance privées sont des méthodes disponibles dans les instances de classe privées, dont l'accès est restreint de la même manière que les champs d'instance privés.</p> + +<pre class="brush: js notranslate">class ClassWithPrivateMethod { + #privateMethod() { + return 'hello world' + } + + getPrivateMessage() { + return this.#privateMethod() + } +} + +const instance = new ClassWithPrivateMethod() +console.log(instance.getPrivateMessage()) +// expected output: "hello world"</pre> + +<p>Les méthodes d'instance privées peuvent être des fonctions génératrices, asynchones ou génératrices asynchrones. Des accesseurs (getters) et des mutateurs (setters) privés sont aussi posibles :</p> + +<pre class="brush: js notranslate">class ClassWithPrivateAccessor { + #message + + get #decoratedMessage() { + return `✨${this.#message}✨` + } + set #decoratedMessage(msg) { + this.#message = msg + } + + constructor() { + this.#decoratedMessage = 'hello world' + console.log(this.#decoratedMessage) + } +} + +new ClassWithPrivateAccessor(); +// expected output: "✨hello world✨" +</pre> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Spécification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('Public and private instance fields', '#prod-FieldDefinition', 'FieldDefinition')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + + + +<p>{{Compat("javascript.classes.private_class_fields")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li><a href="https://wiki.developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Classes/Class_fields">Champs de classe publiques</a></li> + <li><a href="https://rfrn.org/~shu/2018/05/02/the-semantics-of-all-js-class-elements.html">The Semantics of All JS Class Elements</a></li> +</ul> |