Les attributs privés en JavaScript
Tags: javascript, typescript, french, francais
Published: 2020-04-09 14:11:55

Aussi étonnant que cela puisse paraître, nous ne pouvons pas avoir d'attributs ou de méthodes privés dans une classe en **JavaScript**. La solution aujourd'hui est de le simuler grâce au design pattern **[module](https://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript)** et aux **[closures](https://developer.mozilla.org/fr/docs/Web/JavaScript/Closures)**.

Toutefois, le standard est en train d'évoluer et il est probable que le langage intègre prochainement le support d'une telle notion. Nous allons voir ça dans cet article.

## Draft Stage 3

Nous avons évoqué cette _feature_ dans l'article ["Roadmap ES.Next, où en sommes-nous ?"](https://www.younup.fr/blog/roadmap-es-next-ou-en-sommes-nous). Une draft qui atteint le **stage 3** est une **draft** en cours de finalisation.

La proposition est disponible sur GitHub : [Private methods and getter/setters for JavaScript classes](https://github.com/tc39/proposal-private-methods)

Malheureusement, il n'y a pas eu d'évolution depuis 6 mois, elle n’intégrera pas la nouvelle mouture du standard qui sortira cette année : **ES2020**.

### Concrètement, qu'est-ce que cela apporte ?

Quand on parle d'attributs et de méthodes privés dans une [classe](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Classes), il est question de [POO](https://developer.mozilla.org/fr/docs/Glossaire/POO).

En voici un exemple :

```javascript
class Younup {
  #you = 0;

  constructor() {}

  up() {
    this.#you++;
  }

  #upup() {
    this.#you = this.#you + 2;
  }

  getYou() {
    return this.#you;
  }

  addYouYouAndGetYou() {
    this.#upup();
    return this.#you;
  }
}
```

Dans ce cas précis, le symbole `#` permet :

- soit de rendre votre attribut **privé**,
- Soit de rendre votre méthode **privée**.

Il nous est donc impossible d'appeler ou d'accéder à un attribut privé en dehors de classe. Ce code, par exemple, n'est pas valide :

```javascript
const younup = new Younup();
younup.up();
console.log(younup.#you);    // SyntaxError
younup.#upup();              // SyntaxError
```

## Et dans le monde réel ?

Sans être encore dans le standard, il peut arriver que certains navigateurs embarquent des fonctionnalités expérimentales dans leur dernière version.

Je vous invite à consulter deux excellents sites pour cela : https://caniuse.com/ et https://developer.mozilla.org/fr/.

Au moment de rédiger cet article, seuls les attributs privés ont été implémenté dans trois navigateurs : _Chrome 74_, _Edge 79_ et _Opera 62_.

Les méthodes ne sont pas encore concernées à ce jour.

## Bonjour **TypeScript** 3.8 !

**TypeScript** a décidé de prendre également les devants et d'intégrer les attributs privés.

Voici un exemple de classe avec les deux façons différentes de déclarer des attributs privés en **TypeScript** :

```typescript
class Younup {
  #you = 0;
  private you = 0;

  constructor() {}

  getPrivateYou() {
    return this.you;
  }

  getRealPrivateYou() {
    return this.#you;
  }
}
```

Alors, à quel moment peut-on utiliser le mot clé `private` ou le `#` ?

La _feature_ étant relativement récente, il n'y a pas réellement de discussion à ce sujet.

Avantages du `#` :

- Véritable _privé_, nous ne pouvons pas accéder au `private` d'un objet, comme nous pourrions le faire avec un `(obj as any).variablePrivee` ;
- Adoption du futur standard.

Inconvénients du `#` :

- `#` n'est pas assez répandu sur les navigateurs. _"Under the hood"_, **TypeScript** utilise une `WeakMap` pour garder la référence de la classe et des variables privées. Plus l'utilisation de la classe sera grande, plus la consommation en mémoire le sera également.
- Même s'il n'a aucune valeur au _runtime_, le `private` est beaucoup plus efficace (il n'est pas transpilé).

## Conclusion

Un cap supplémentaire est en train d'être franchi, même si l'adoption complète est trop limitée pour s'y aventurer sur des projets importants.

L'adoption du `#` est donc soumis à la cible de vos plateformes et de vos utilisations.

______

Merci d'avoir lu cet article ! 
Il a été posté initialement sur le [blog](https://www.younup.fr/blog) de @younup_it :
https://www.younup.fr/blog/les-attributs-prives-en-javascript

______
Cover par [Dayne Topkin](https://unsplash.com/@dtopkin1) sur [Unsplash](https://unsplash.com/photos/u5Zt-HoocrM)