Getter / setter ES6 avec fonction flèche

100

J'utilise babel6 et pour mon projet animal de compagnie, je crée un wrapper pour XMLHttpRequest, pour les méthodes que je peux utiliser:

open = (method, url, something) => {
  return this.xhr.open(method, url, something);
}

mais pour les propriétés, la fonction de flèche ne fonctionne pas

cela marche:

get status() { return this.xhr.status; }

mais je ne peux pas utiliser

get status = () => this.xhr.status;

Est-ce intentionnel?

Gabor Dolla
la source
Vous n'avez pas besoin des accolades ou du retour; vous pouvez juste dire (method, url, something) => this.xhr.open(method. url, something).
getfait partie d'un littéral d'objet ou d'une définition de classe, une affectation de variable ne l'est pas. Pourquoi pensez-vous qu'ils devraient fonctionner de la même manière?
Bergi
1
status => this.xhr.status(syntaxe c # 7) ou peut get status() => this.xhr.status- être aurait-il été un excellent sucre syntaxique pour la lisibilité, mais Javascript et non Typescript ne le supporte pas (encore?)
Charles HETIER

Réponses:

109

Selon la grammaire ES2015, une propriété sur un littéral d'objet ne peut être que l'une des quatre choses suivantes:

PropriétéDéfinition :

  • IdentifierRéférence
  • PropertyName : AssignmentExpression
  • MéthodeDéfinition

Le seul de ces types qui autorise un interligneget est MethodDefinition :

Méthode Définition :

  • PropertyName ( StrictFormalParameters ) { FunctionBody }
  • GénérateurMéthode
  • get PropertyName ( ) { FunctionBody }
  • set PropertyName ( PropertySetParameterList ) { FunctionBody }

Comme vous pouvez le voir, le getformulaire suit une grammaire très limitée qui doit être de la forme

get NAME () { BODY }

La grammaire n'autorise pas les fonctions du formulaire get NAME = ....

apsillers
la source
Merci pour votre aide, j'accepte votre réponse. Savez-vous où il est défini que getter / setter ne peut pas être utilisé avec une affectation? Juste curieux.
Gabor Dolla
@GaborDolla Modifié pour faire référence à la grammaire littérale de l'objet dans la spécification ECMAScript.
apsillers
35

La réponse acceptée est excellente. C'est le meilleur si vous êtes prêt à utiliser une syntaxe de fonction normale au lieu d' une «syntaxe de fonction de flèche» compacte.

Mais peut-être que vous aimez vraiment les fonctions fléchées; peut-être que vous utilisez la fonction de flèche pour une autre raison qu'une syntaxe de fonction normale ne peut pas remplacer ; vous aurez peut-être besoin d'une solution différente.

Par exemple, je remarque que OP utilise this, vous voudrez peut-être lier thislexicalement; aka "non contraignant de ceci" ), et les fonctions fléchées sont bonnes pour cette liaison lexicale.

Vous pouvez toujours utiliser une fonction flèche avec un getter via la Object.definePropertytechnique.

{
  ...
  Object.defineProperty(your_obj, 'status', { 
     get : () => this.xhr.status 
  });
  ...
}

Voir les mentions de la object initializationtechnique (aka get NAME() {...}) vs la definePropertytechnique (aka get : ()=>{}) . Il y a au moins une différence significative, l'utilisation definePropertyrequiert que les variables existent déjà:

Définition d'un getter sur des objets existants

c'est-à-dire avec Object.definePropertyvous devez vous assurer que your_obj(dans mon exemple) existe et est sauvegardé dans une variable (alors qu'avec a object-initializationvous pouvez retourner un objet-littéral dans votre initialisation d'objet:) {..., get(){ }, ... }. Plus d'informations sur Object.definePropertyspécifiquement, ici

Object.defineProperty(...)semble avoir un support de navigateur comparable à la get NAME(){...}syntaxe; navigateurs modernes, IE 9.

Le pois rouge
la source
10
Intelligent, mais c'est finalement beaucoup plus verbeux que juste:get status() { return this.xhr.status; }
devuxer
2
@devuxer Je suis d'accord que c'est trop verbeux. Mais pour être clair, vous this devez être l'objet dans lequel vous êtes get status() { ... }défini. Mais mon this pourrait être autre chose, en raison de différences de liaison lexicale, non?
The Red Pea
2
D'accord ... bien qu'en pratique, je n'ai pas rencontré de cas où ce thisn'est pas ce que je veux dans un accesseur get. (Les thisavantages de liaison des fonctions fléchées semblent entrer en jeu lors du passage de fonctions, comme avec les gestionnaires d'événements et les rappels.)
devuxer
3
Je suis d'accord, j'utilise fréquemment une grosse flèche + des liaisons lexicales ()=>{}pour les rappels que je passe à une promesse , comme $http(...).then((promise_result)=> this...})). Si je n'utilise pas de grosse flèche, thisreprésentera l' Windowobjet global ; pas très utile. Mais j'ai rarement (jamais?) Utilisé ()=>{}comme fonction pour un "get accessor" comme vous dites ... au moins à l' thisintérieur de get()va représenter l'objet sur lequel get()est défini (ce qui est déjà plus utile que Window; donc il n'y a pas besoin d'utiliser une fonction de grosse flèche!)
The Red Pea