Programmez! #240 est en kiosque

En raison de la situation de redressement judiciaire de Presstalis qui s'est superposée à la crise sanitaire covid-19, la sortie dans les kiosques de  Programmez! #240 a été profondément perturbée.

Mais ça y est, il arrive ! Vous le trouverez chez votre marchand de journaux ce mercredi 27 mai !

Il est malgré tout possible qu'il ait encore quelque jours de retard dans quelques régions.

Une évolution possible des classes en JavaScript en 2019

Par:
fredericmazue

jeu, 24/01/2019 - 08:04

Le Technical Committee 39, ou TC39 travaille actuellement sur les nouvelles fonctionnalités à intégrer à ES2019. Les propositions sur lesquelles travaille ce comité sont disponibles sur GitHub.  Elles sont très nombreuses.

Parmi elles nous remarquons une évolution des déclarations de champs, dans une classe.

Soit une classe qui encapsule une compteur de clics sur un widget. Auparavant nous pouvions avoir : 

class Counter extends HTMLElement {
  clicked() {
    this.x++;
    window.requestAnimationFrame(this.render.bind(this));
  }
 
 constructor() {
    super();
    this.onclick = this.clicked.bind(this);
    this.x = 0;
  }
 
 connectedCallback() { this.render(); }
 
 render() {
    this.textContent = this.x.toString();
  }
}

window.customElements.define('num-counter', Counter);

Avec la nouvelle proposition, le code devient

class Counter extends HTMLElement {
  x = 0;

  clicked() {
    this.x++;
    window.requestAnimationFrame(this.render.bind(this));
  }
 
 constructor() {
    super();
    this.onclick = this.clicked.bind(this);
  }
 
 connectedCallback() { this.render(); }
 
 render() {
    this.textContent = this.x.toString();
  }
}
window.customElements.define('num-counter', Counter);

Le champ x peut aussi être déclaré sans initialisation. La proposition souligne qu'avec cette déclaration au début du code d'une classe, cette dernière est mieux auto-documentée, et que les instances passent par moins de changement d'état, puisque les champs ainsi déclarés sont toujours présents.

Avec cette proposition, les champs de classes peuvent être privés. Il n'est alors possible d'y accéder que via des accesseurs (getters et setters). Un champ privé est préfixé par le signe #, comme ceci :

class Counter extends HTMLElement {
  #x = 0;
 
 clicked() {
    this.#x++;
    window.requestAnimationFrame(this.render.bind(this));
  }
 
 constructor() {
    super();
    this.onclick = this.clicked.bind(this);
  }
 
 connectedCallback() { this.render(); }
 
 render() {
    this.textContent = this.#x.toString();
  }
}
window.customElements.define('num-counter', Counter);

Les méthodes de classes peuvent également être privées. Là encore elles seront préfixées par le signe #, comme ceci :

class Counter extends HTMLElement {
  #xValue = 0;
 
get #x() { return #xValue; }

  set #x(value) {
    this.#xValue = value;
    window.requestAnimationFrame(this.#render.bind(this));
  }

  #clicked() {
    this.#x++;
  }
 
constructor() {
    super();
    this.onclick = this.#clicked.bind(this);
  }
 
connectedCallback() { this.#render(); }
 
#render() {
    this.textContent = this.#x.toString();
  }
}
window.customElements.define('num-counter', Counter); 

Bien sûr, il ne s'agit pour l'instant que de propositions. L'avenir nous dira si celles-ci sont adoptées par le comité TC39.