Une deuxième approche, de plus en plus populaire et même franchement “hype” à ce stade, repose sur la syntaxe à venir des initialiseurs de champ d’instance. On la retrouve dans beaucoup de tutos et guides, y compris des guides officiels.

L’idée consiste à remplacer la syntaxe de déclaration de méthode concise par un initialiseur de champ d’instance, comme dans cet exemple.  On peut alors se passer d’écrire une liaison explicite dans le constructeur.

Cette approche a deux avantages : d’une part, elle figure à même la déclaration, plutôt qu’ailleurs dans le code. Quand je cherche la définition de la méthode sayHi(), je tombe dessus. Par ailleurs, c’est aussi performant que la liaison explicite dans le constructeur, puisqu’en fait en interne ça revient à peu près au même, comme on va le voir.

Il y a en revanche inconvénient à mon sens majeur : l’intention est masquée. Rien ne dit que le recours à cette syntaxe pour déclarer la méthode vient effectivement d’une décision volontaire de liaison. D'une part, si la personne qui lit ce code n’est pas au fait des problématiques de liaison, cet aspect est totalement invisible.

D’autre part, je vois arriver gros comme une maison le copier-coller systématique de cette syntaxe pour toute déclaration de méthode, sans se poser de question. Un peu comme on a vu fleurir les définitions de fonctions sous forme d’expressions (var fx = function(…)) plutôt que sous forme de déclarations (function fx(…)), de façon parfaitement inutile et même contre-productive, puisqu’elle ne permet pas le hoisting par exemple.

Bref, je ne suis pas fan de cette approche, je vous le dis. Voyons quand même un exemple.

(Exemple 20-guarantee-field-initializer.js)

On a décliné ici l’exemple précédent, et vous voyez qu’à l’exécution, le this est bien le bon !

Mais au fait, pourquoi cette syntaxe résout-elle notre besoin de liaison, finalement ?

Eh bien, un initialiseur de champ au sein d’une classe est en fait du sucre syntaxique pour la présence de ce code dans le constructeur, préfixé par this.”. C’est littéralement la même chose.

Qui plus est, comme la valeur est une fonction fléchée, elle ne redéfinit par this, de sorte que celui qu’elle « voit » dans son corps de fonction est celui de la portée conteneur, donc le constructeur. Vous l’imaginez bien, au sein du constructeur, this est forcément l’instance. C’est pourquoi il est possible (et surprenant les premières fois) d’utiliser this au sein des expressions passées aux initialiseurs de champ, pour désigner l’instance en vigueur.