Funkcja pobierająca / ustawiająca ES6 z funkcją strzałki

107

Używam babel6 i dla mojego projektu dla zwierząt tworzę opakowanie dla XMLHttpRequest, dla metod, których mogę użyć:

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

ale dla właściwości funkcja strzałki nie działa

to działa:

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

ale nie mogę użyć

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

Czy jest to zamierzone?

Gabor Dolla
źródło
Nie potrzebujesz nawiasów klamrowych ani powrotu; możesz po prostu powiedzieć (method, url, something) => this.xhr.open(method. url, something).
getjest częścią literału obiektu lub definicji klasy, przypisanie zmiennej nie jest. Jak myślisz, dlaczego powinny działać podobnie?
Bergi
2
status => this.xhr.status(c # 7 syntaxe) lub może get status() => this.xhr.statusrzeczywiście byłby świetnym cukrem składniowym dla czytelności, ale Javascript nie Typescript (jeszcze?) go nie obsługuje
Charles HETIER

Odpowiedzi:

114

Zgodnie z gramatyką ES2015, właściwość literału obiektu może być tylko jedną z czterech rzeczy:

WłaściwośćDefinicja :

  • IdentifierReference
  • PropertyName : AssignmentExpression
  • MethodDefinition

Jedynym tego typu, który umożliwia prowadzenie, getjest MethodDefinition :

Metoda Definicja :

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

Jak widać, getforma ma bardzo ograniczoną gramatykę, która musi mieć formę

get NAME () { BODY }

Gramatyka nie dopuszcza funkcji formularza get NAME = ....

apsillers
źródło
Dziękuję za pomoc, przyjmuję odpowiedź. Czy wiesz, gdzie zdefiniowano, że metody pobierającej / ustawiającej nie można używać z przypisaniem? Po prostu ciekawy.
Gabor Dolla
@GaborDolla Edytowano, aby odnosić się do gramatyki literału obiektu w specyfikacji ECMAScript.
apsillers
39

Przyjęta odpowiedź jest świetna. Najlepiej, jeśli chcesz używać normalnej składni funkcji zamiast zwartej „składni funkcji strzałkowej”.

Ale może naprawdę lubisz funkcje strzałkowe; być może używasz funkcji strzałki z innego powodu, którego normalna składnia funkcji nie może zastąpić ; możesz potrzebować innego rozwiązania.

Na przykład, zauważam użycie OP this, możesz chcieć łączyć się thisleksykalnie; aka „niewiążące tego” ), a funkcje strzałkowe są dobre dla tego leksykalnego wiązania.

Nadal możesz używać funkcji strzałkowej z funkcją pobierającą za pomocą tej Object.definePropertytechniki.

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

Zobacz wzmianki o object initializationtechnice (aka get NAME() {...}) kontra definePropertytechnika (aka get : ()=>{}) . Istnieje co najmniej jedna znacząca różnica, użycie definePropertywymaga, aby zmienne już istniały:

Definiowanie metody pobierającej na istniejących obiektach

tzn. Object.definePropertymusisz upewnić się, że your_obj(w moim przykładzie) istnieje i jest zapisany w zmiennej (podczas gdy z a object-initializationmożesz zwrócić literał obiektowy w inicjalizacji obiektu:) {..., get(){ }, ... }. Więcej informacji na ten temat znajdziesz Object.definePropertytutaj

Object.defineProperty(...)wydaje się, że obsługuje przeglądarkę porównywalną ze get NAME(){...}składnią; nowoczesne przeglądarki, IE 9.

Groszek czerwony
źródło
11
Sprytne, ale ostatecznie jest znacznie bardziej szczegółowe niż tylko:get status() { return this.xhr.status; }
devuxer,
2
@devuxer Zgadzam się, że to zbyt szczegółowe. Ale żeby było jasne, twój this musi być obiekt, w którym twój get status() { ... }jest zdefiniowany. Ale moje this mogłoby być czymś innym, ze względu na różnice leksykalne, prawda?
The Red Pea
2
Zgadzam się ... chociaż w praktyce nie spotkałem się z przypadkiem, w którym thisnie jest to, czego chcę w akcesorium get. ( thisWiążące zalety funkcji strzałkowych wydają się wchodzić w grę podczas przekazywania funkcji, tak jak w przypadku obsługi zdarzeń i wywołań zwrotnych.)
devuxer
3
Zgadzam się, często używam grubej strzałki + leksykalnych powiązań ()=>{}dla wywołań zwrotnych, które przekazuję do Obietnicy , jak $http(...).then((promise_result)=> this...})). Jeśli nie używam fat-arrow, thisbędzie reprezentować Windowobiekt globalny ; niezbyt przydatne. Ale rzadko (nigdy?) Używam ()=>{}jako funkcji „get accessor”, jak mówisz ... przynajmniej thiswewnątrz get()będzie reprezentował obiekt, na którym get()jest zdefiniowany (co jest już bardziej przydatne niż Window; więc nie ma potrzeby używania funkcja grubej strzały!)
The Red Pea
1
definePropertyPodejście jest użyteczne w pętli. W tej chwili po prostu użyłem go do ujawnienia niektórych właściwości schłodzonego obiektu z zawierającego.
Edurne Pascual