Getter / setter ES6 con funzione freccia


100

Sto usando babel6 e per il mio progetto preferito sto creando un wrapper per XMLHttpRequest, per i metodi che posso usare:

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

ma per le proprietà la funzione freccia non funziona

questo funziona:

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

ma non posso usare

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

È intenzionale?


Non hai bisogno delle parentesi graffe o del ritorno; puoi solo dire (method, url, something) => this.xhr.open(method. url, something).

getè una parte di un oggetto letterale o di una definizione di classe, l'assegnazione di una variabile non lo è. Perché pensi che dovrebbero funzionare allo stesso modo?
Bergi

1
status => this.xhr.status( get status() => this.xhr.statussintassi c # 7) o forse sarebbe stato davvero un ottimo zucchero sintattico per la leggibilità ma Javascript non Typescript non lo supporta (ancora?)
Charles HETIER

Risposte:


109

Secondo la grammatica ES2015, una proprietà su un oggetto letterale può essere solo una delle quattro cose:

PropertyDefinition :

  • IdentifierReference
  • PropertyName : AssignmentExpression
  • Metodo Definizione

L'unico di questi tipi che consente un lead getè MethodDefinition :

Metodo Definizione :

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

Come puoi vedere, la getforma segue una grammatica molto limitata che deve essere della forma

get NAME () { BODY }

La grammatica non consente le funzioni del modulo get NAME = ....


Grazie per il tuo aiuto, accetto la tua risposta. Sai dove è definito che getter / setter non può essere utilizzato con un incarico? Solo curioso.
Gabor Dolla

@GaborDolla Modificato per fare riferimento alla grammatica letterale dell'oggetto nella specifica ECMAScript.
apsillers

35

La risposta accettata è ottima. È la soluzione migliore se si desidera utilizzare la sintassi della funzione normale invece della sintassi compatta della "funzione freccia".

Ma forse ti piacciono molto le funzioni delle frecce; forse usi la funzione freccia per un altro motivo che una normale sintassi di funzione non può sostituire ; potresti aver bisogno di una soluzione diversa.

Ad esempio, ho notato che l'OP utilizza this, potresti voler legare thislessicalmente; aka "non vincolante di questo" ), e le funzioni freccia sono buone per quel vincolo lessicale.

È ancora possibile utilizzare una funzione freccia con un getter tramite la Object.definePropertytecnica.

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

Vedi menzioni di object initializationtecnica (aka get NAME() {...}) vs definePropertytecnica (aka get : ()=>{}) . C'è almeno una differenza significativa, l'utilizzo definePropertyrichiede che le variabili già esistano:

Definizione di un getter su oggetti esistenti

cioè con Object.definePropertydevi assicurarti che your_obj(nel mio esempio) esista e venga salvato in una variabile (mentre con a object-initializationpotresti restituire un oggetto letterale nell'inizializzazione dell'oggetto :) {..., get(){ }, ... }. Maggiori informazioni in Object.definePropertyparticolare, qui

Object.defineProperty(...)sembra avere un supporto browser paragonabile alla get NAME(){...}sintassi; browser moderni, IE 9.


10
Intelligente, ma alla fine è molto più prolisso di un semplice:get status() { return this.xhr.status; }
devuxer

2
@ devuxer Sono d'accordo che sia troppo prolisso. Ma per essere chiari, il tuo this deve essere l'oggetto in cui get status() { ... }è definito. Ma il mio this potrebbe essere qualcos'altro, a causa di differenze lessicali vincolanti, giusto?
The Red Pea

2
D'accordo ... anche se in pratica, non mi sono imbattuto in un caso in cui thisnon è quello che voglio in un get accessor. (I thisvantaggi di associazione delle funzioni freccia sembrano entrare in gioco quando si passano le funzioni, come con i gestori di eventi e i callback.)
devuxer

3
Sono d'accordo, uso spesso fat arrow + binding lessicali ()=>{}per i callback che passo a una Promise , come $http(...).then((promise_result)=> this...})). Se non uso fat-arrow, thisrappresenterà l' Windowoggetto globale ; non molto utile. Ma raramente (mai?) Ho usato ()=>{}come funzione per un "get accessor" come dici tu ... almeno thisall'interno di get()rappresenterà l'oggetto su cui get()è definito (che è già più utile di Window; quindi non c'è bisogno di usare una funzione di freccia grassa!)
The Red Pea
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.