web-dev-qa-db-fra.com

ES6 getter / setter avec fonction de flèche

J'utilise babel6 et, pour mon projet animalier, 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?

69
Gabor Dolla

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

PropertyDefinition:

  • IdentifierReference
  • PropertyName: AssignmentExpression
  • MethodDefinition

Le seul de ces types qui autorise un get en tête est MethodDefinition :

MethodDefinition:

  • PropertyName( StrictFormalParameters){ FunctionBody}
  • GeneratorMethod
  • get PropertyName(){ FunctionBody}
  • set PropertyName ( PropertySetParameterList){ FunctionBody}

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

get NAME () { BODY }

La grammaire ne permet pas les fonctions de la forme get NAME = ....

78
apsillers

La réponse acceptée est géniale. C'est la meilleure solution si vous voulez utiliser normal la syntaxe de la fonction au lieu de compact "syntaxe de la fonction de flèche".

Mais peut-être aimez-vous vraiment les fonctions de flèche; peut-être utilisez-vous 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 bind this de manière lexique; alias "non-contraignant de cette" ), cette liaison lexicale.

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

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

Voir les mentions de la technique object initialization (aka get NAME() {...}) vs defineProperty technique (ou get : ()=>{}) . Il y a au moins une différence significative, utiliser defineProperty nécessite que les variables existent déjà:

Définir un getter sur objets existants

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

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

24
The Red Pea