Wofür sind Getter und Setter in ECMAScript 6-Klassen?

101

Ich bin verwirrt darüber, wozu Getter und Setter in ECMAScript 6-Klassen gut sind. Was ist der Zweck? Unten ist ein Beispiel, auf das ich mich beziehe:

class Employee {

    constructor(name) {
        this._name = name;
    }

    doWork() {
        return `${this._name} is working`;
    }

    get name() {
        return this._name.toUpperCase();
    }

    set name(newName){
        if(newName){ 
            this._name = newName;
        }
    }
}
TruMan1
quelle
1
Es ist ähnlich wie in C #, wenn Sie etwas darüber wissen.
Arturo Torres Sánchez
Verwandte Themen
Bergi
Ein guter Artikel, der genau dies erklärt, finden Sie unter: coryrylan.com/blog/javascript-es6-class-syntax "In unserer obigen Klasse haben wir einen Getter und Setter für unsere Namenseigenschaft . Wir verwenden die Konvention '_', um ein Hintergrundfeld zu erstellen Wenn unsere get-Eigenschaft jedes Mal aufgerufen wird, wenn get oder set aufgerufen wird, würde dies einen Stapelüberlauf verursachen. "... Es spricht auch davon, dass die Variable nicht wirklich 'privat' ist, aber es gibt zahlreiche neue Möglichkeiten, private Variablen in zu erstellen JS-Klassen; Mein Favorit ist nur Typescript, aber ich habe auch den Symbol-Ansatz verwendet
webdevinci

Antworten:

107

Mit diesem Setter und Getter können Sie die Eigenschaften direkt verwenden (ohne die Klammer zu verwenden).

var emp = new Employee("TruMan1");

if (emp.name) { 
  // uses the get method in the background
}

emp.name = "New name"; // uses the setter in the background

Dies dient nur zum Festlegen und Abrufen des Werts der Eigenschaft.

David Laberge
quelle
1
Meinten Sie Eigentum statt Attribut?
Etwas
Gutes Auge, @Krizzu. Attribute existieren in JavaScript und sind völlig andere Dinge als Eigenschaften. Die Antwort bezieht sich in der Tat auf Eigenschaften und nicht auf Attribute. Ich habe die Antwort bearbeitet. Ich glaube nicht, dass es dem Antwortenden etwas ausmacht. :)
Ray Toal
Ich bin mir nicht ganz sicher, ob dies wirklich ein solcher Vorteil ist, es verbirgt irgendwie die Vorstellung, Setter / Getter zu verwenden. Ein Kunde einer Klasse mag denken, dass er direkt Eigenschaften verwendet, bei denen dies nicht angemessen ist, aber ich stimme zu, dass er das Prinzip des Versteckens von Informationen / Details einhält. Vielleicht, wenn wir dies konsequent verwenden, erleichtert es die Verwendung und ich muss mich nur mehr daran gewöhnen ...
Christof Kälin
Können Sie in einem Setter mehrere Parameter übergeben, wenn ja, wie verwenden Sie ihn? @ David Laberge
Vignesh S
Wenn Sie Setter und Getter manuell erstellen möchten, finden Sie hier ein gutes Beispiel von coryrylan.com/blog/javascript-es6-class-syntax Set: set name(newName) { this._name = newName; }Get:get name() { return this._name.toUpperCase(); }
Jim Doyle
48

Getter und Setter in ES6 dienen demselben Zweck wie in anderen Sprachen ... einschließlich ES5. ES5 erlaubt Getter und Setter bereits über Object.defineProperty, obwohl sie weniger sauber und umständlicher zu bedienen sind.

Getter und Setter ermöglichen es Ihnen effektiv, die Standardnotation für den Zugriff auf Eigenschaften für Lese- und Schreibvorgänge zu verwenden, während Sie dennoch anpassen können, wie die Eigenschaft abgerufen und mutiert wird, ohne dass explizite Getter- und Setter-Methoden erforderlich sind.

In der obigen Mitarbeiterklasse bedeutet dies, dass Sie wie folgt auf die nameEigenschaft zugreifen können:

console.log(someEmployee.name);

Es würde wie ein normaler Eigenschaftszugriff aussehen , aber es würde tatsächlich toUpperCaseden Namen aufrufen, bevor es zurückgegeben wird. In ähnlicher Weise:

someEmployee.name = null;

würde auf den Setter zugreifen und die interne _nameEigenschaft aufgrund der in nameSetter eingeführten Schutzklausel nicht ändern .

Siehe auch die allgemeine Frage Warum Getter und Setter verwenden? Weitere Informationen dazu, warum es hilfreich ist, die Funktionalität des Mitgliederzugriffs zu ändern.

Alexis King
quelle
3

ES6-Getter und -Setter haben eine wesentlich andere Motivation als ähnliche Konzepte in Java.

In Java ermöglichen Getter und Setter einer Klasse, eine JavaBean zu definieren. Der Punkt von Gettern und Setzern ist, dass die Bean eine vollständig orthogonale "Schnittstelle" von der durch öffentliche Felder implizierten haben kann. Ich kann also ein Feld "name" haben, das KEINE JavaBean-Eigenschaft ist, und ich kann eine JavaBean-Eigenschaft "address" haben, die KEIN Feld ist.

JavaBean-Eigenschaften können auch von Tausenden von Frameworks (z. B. Hibernate) über Java Reflection "entdeckt" werden. Daher sind Getter und Setter Teil einer Standardmethode zum "Freilegen" von Bohneneigenschaften.

Getter und Setter haben als Funktionen auch den Wert, dass sie die Implementierung "abstrahieren". Es kann entweder ein Feld oder ein berechneter ("synthetischer") Wert sein. Wenn ich also eine Bean-Eigenschaft namens "Postleitzahl" habe, beginnt diese als gespeicherte Zeichenfolge. Angenommen, ich möchte es in einen Wert ändern, der aus Adresse / Stadt / Bundesland berechnet wird.

Wenn ich ein Feld verwende, wird dieser Code unterbrochen:

      String zipcode = address.zipcode();

Aber wenn ich einen Getter benutze, bricht das nicht:

      String zipcode = address.getZipcode();

JavaScript hat nichts wie JavaBeans. Soweit ich gelesen habe, ist der beabsichtigte Wert von GET und SET auf die oben genannten "synthetischen" (berechneten) Eigenschaften beschränkt.

Aber es ist etwas besser als Java, da Java es Ihnen nicht erlaubt, ein "Feld" kompatibel in eine Methode zu konvertieren, ES6 GET und SET dies jedoch zulassen.

Das heißt, wenn ich habe:

       var zipcode = address.zipcode;

Wenn ich die Postleitzahl von einer Standardobjekteigenschaft in einen Getter ändere, ruft der obige Code jetzt die GET-Funktion auf.

Beachten Sie, dass wenn ich GET nicht in die Definition aufgenommen hätte, dies NICHT die Postleitzahl-GET-Methode aufrufen würde. Stattdessen würde es lediglich die Postleitzahl der Funktion der var zuweisen.

Daher denke ich, dass dies einige wichtige Unterscheidungen sind, um zwischen Java- und JavaScript ES6-Get- und -Setzern zu verstehen.

DaBlick
quelle
0
class Employee {

    constructor(name) {
      this._name = name;
    }

    doWork() {
      return `${this._name} is working`;
    }

    get name() {
      // when you get this by employeeInstance.mame
      // the code below will be triggered
      // and you can do some logic here
      // just like `console.log` something you want
      console.log('get triggered!')
      return this._name.toUpperCase();
    }

    set name(newName) {
      // the same as `get`
      // when you employeeInstance.mame = 'xxx'
      // the code blew will be trigged
      // and you can also do some logic 
      // like here is a `console.log` and `if check`
      console.log('set triggered!')
      if (newName) {
        this._name = newName;
      }
    }
  }

  const employeeInstance = new Employee('mike')
  employeeInstance.name
  employeeInstance.name = '' // this won't be success, because the `if check`
  console.log(employeeInstance.name)

  // => 
  // get triggered
  // set triggered
  // get triggered
  // MIKE

Jedenfalls ist das getterund setterwie ein Spion. Es erkennt die Eigenschaft eines Objekts, sodass Sie jedes Mal etwas tun können, wenn Sie den Wert der Eigenschaft abrufen oder festlegen.

RandomYang
quelle