Les attributs privés en JavaScript

Benjamin🦸‍♂️Auzanneau™ - Apr 9 '20 - - Dev Community

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 et aux 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 ?". 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

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, il est question de POO.

En voici un exemple :

class Younup {
  #you = 0;

  constructor() {}

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

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

  getYou() {
    return this.#you;
  }

  addYouYouAndGetYou() {
    this.#upup();
    return this.#you;
  }
}
Enter fullscreen mode Exit fullscreen mode

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 :

const younup = new Younup();
younup.up();
console.log(younup.#you);    // SyntaxError
younup.#upup();              // SyntaxError
Enter fullscreen mode Exit fullscreen mode

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 :

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

  constructor() {}

  getPrivateYou() {
    return this.you;
  }

  getRealPrivateYou() {
    return this.#you;
  }
}
Enter fullscreen mode Exit fullscreen mode

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 de @younup_it :
https://www.younup.fr/blog/les-attributs-prives-en-javascript


Cover par Dayne Topkin sur Unsplash

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player