ES6 Getter / Setter mit Pfeilfunktion


100

Ich verwende babel6 und erstelle für mein Lieblingsprojekt einen Wrapper für XMLHttpRequest für die Methoden, die ich verwenden kann:

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

aber für die Eigenschaften funktioniert die Pfeilfunktion nicht

das funktioniert:

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

kann ich aber nicht benutzen

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

Ist das beabsichtigt?


Sie brauchen weder die geschweiften Klammern noch die Rückgabe. du kannst es einfach sagen (method, url, something) => this.xhr.open(method. url, something).

getist Teil eines Objektliteral oder einer Klassendefinition, eine Variablenzuweisung nicht. Warum sollten sie Ihrer Meinung nach gleich funktionieren?
Bergi

1
status => this.xhr.status(c # 7 Syntax) oder get status() => this.xhr.statuswäre vielleicht tatsächlich ein großartiger syntaktischer Zucker für die Lesbarkeit gewesen, aber Javascript nicht Typescript unterstützt es (noch?) nicht
Charles HETIER

Antworten:


107

Gemäß der ES2015-Grammatik kann eine Eigenschaft in einem Objektliteral nur eines von vier Dingen sein:

PropertyDefinition :

  • IdentifierReference
  • PropertyName : AssignmentExpression
  • MethodDefinition

Der einzige dieser Typen, der eine führende Position zulässt, getist MethodDefinition :

MethodDefinition :

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

Wie Sie sehen können, getfolgt das Formular einer sehr begrenzten Grammatik, die von der Form sein muss

get NAME () { BODY }

Die Grammatik erlaubt keine Funktionen des Formulars get NAME = ....


Vielen Dank für Ihre Hilfe, ich akzeptiere Ihre Antwort. Wissen Sie, wo definiert ist, dass Getter / Setter nicht mit einer Aufgabe verwendet werden können? Nur neugierig.
Gabor Dolla

@GaborDolla Bearbeitet, um auf die Objektliteralgrammatik in der ECMAScript-Spezifikation zu verweisen.
Apsiller

35

Die akzeptierte Antwort ist großartig. Es ist am besten, wenn Sie bereit sind, die normale Funktionssyntax anstelle der kompakten "Pfeilfunktionssyntax" zu verwenden.

Aber vielleicht magst du Pfeilfunktionen wirklich; Vielleicht verwenden Sie die Pfeilfunktion aus einem anderen Grund, den eine normale Funktionssyntax nicht ersetzen kann . Möglicherweise benötigen Sie eine andere Lösung.

Ich stelle beispielsweise fest, dass OP verwendet thiswird. Möglicherweise möchten Sie lexikalisch binden this. alias "Nichtbindung davon" ) und Pfeilfunktionen sind gut für diese lexikalische Bindung.

Sie können weiterhin eine Pfeilfunktion mit einem Getter über die Object.definePropertyTechnik verwenden.

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

Siehe Erwähnungen von object initializationTechnik (aka get NAME() {...}) gegen definePropertyTechnik (aka get : ()=>{}) . Es gibt mindestens einen signifikanten Unterschied, für dessen Verwendung definePropertydie Variablen bereits vorhanden sind:

Definieren eines Getters für vorhandene Objekte

Das heißt, Object.definePropertySie müssen sicherstellen, dass your_obj(in meinem Beispiel) vorhanden und in einer Variablen gespeichert ist (während Sie mit a object-initializationein Objektliteral in Ihrer Objektinitialisierung zurückgeben können :) {..., get(){ }, ... }. Mehr Infos dazu Object.definePropertyhier

Object.defineProperty(...)scheint eine vergleichbare Browserunterstützung wie die get NAME(){...}Syntax zu haben; moderne Browser, IE 9.


10
Clever, aber letztendlich viel ausführlicher als nur:get status() { return this.xhr.status; }
Devuxer

2
@devuxer Ich stimme zu, es ist zu ausführlich. Aber nur um klar zu sein, this müssen Sie das Objekt sein, in dem Sie get status() { ... }definiert sind. Aber mein this könnte aufgrund lexikalischer Bindungsunterschiede etwas anderes sein, oder?
Die rote Erbse

2
Stimmen Sie zu ... obwohl ich in der Praxis nicht auf einen Fall thisgestoßen bin, in dem ein Get Accessor nicht das ist, was ich will. (Die thisverbindlichen Vorteile von Pfeilfunktionen scheinen bei der Weitergabe von Funktionen wie bei Ereignishandlern und Rückrufen zum Tragen zu kommen.)
Devuxer

3
Ich stimme zu, ich verwende häufig fette Pfeile + lexikalische Bindungen ()=>{}für die Rückrufe, die ich an ein Versprechen weitergebe , wie z $http(...).then((promise_result)=> this...})). Wenn ich keinen Fettpfeil verwende, thiswird das globale WindowObjekt dargestellt. nicht sehr nützlich. Aber ich habe selten (nie?) ()=>{}Als Funktion für einen "Get Accessor" verwendet, wie Sie sagen ... zumindest thisinnerhalb von get()wird das Objekt dargestellt, für das get()definiert ist (was bereits nützlicher ist als Window; es besteht also keine Notwendigkeit, es zu verwenden eine Fettpfeilfunktion!)
Die rote Erbse
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.