Rey: Verständnisfrage JavaScript getter und setter

Beitrag lesen

Hi,

Wenn ich eine Methode mit get und set definiere, dann definiere ich im Grunde ja zwei Methoden mit demselben Bezeichner.

Du definierst keine zwei Methoden, sondern eine Eigenschaft, hinter der zwei Funktionen stehen.

Werden diese beiden darüber unterschieden, dass ich entweder ein oder mehrere Argumente übermittle, oder eben keines?

Du rufst die Getter und Setter nicht wie Methoden auf. Du liest bzw. schreibst einfach das Attribut.

alert(myCar.color); // Getter
myCar.color = 'red' // Setter
alert(myCar.type);  // Getter
myCar.type = 'SUV'  // Setter

Vielleicht verwechselst du das mit anderen Sprachen, wo Getter und Setter normale Methoden sind (Java?):

object.getProperty();
object.setProperty(value);

Das kann man in JS zwar auch machen, das ist aber nicht gemeint, wenn von Gettern und Settern die Rede ist. Da geht es um das Lesen und Setzen von Eigenschaften. Man kann zwei Funktionen hinterlegen, die aufgerufen werden, wenn objekt.eigenschaft gelesen bzw. mit objekt.eigenschaft = ... geschrieben wird.

Und wenn dem so ist, wäre es dann nicht sinnvoll mit diesen Methoden einen Wert zu verändern, der ansonsten unerreichbar wäre (eine Variable in einer Closure, deren getter und setter dann natürlich nach dem revealing pattern erstellt werden müssten), anstatt eine Eigenschaft mit einem Bezeichner mit einer beliebigen Anzahl an Unterstrichen zu versehen?

Ja, das wäre besser. Ansonsten haben die Getter/Setter keinen Vorteil gegenüber einer "dummen" Eigenschaft. Zwingend nötig ist es aber nicht.

Die Lösung mit einer Closures und einer "überladenen" Methode mit zwei Aufrufweisen ist eine Möglichkeit. Dabei ist es einfach, den eigentlichen Wert zu verstecken. Dafür hat man eine zusätzliche Schreibweise anstatt einfach objekt.eigenschaft zum Lesen und objekt.eigenschaft = ... zum Schreiben.

Erst mit Symbols in ECMAScript 6 hat man die Möglichkeit, nach außen hin effektiv "unsichtbare" Eigenschaften hinzuzufügen. Dabei muss man aber auch eine Closure oder einen Block verwenden, um das Symbol zu verstecken. ;)

let makeCar;
{
  const typeSymbol = Symbol();
  makeCar = () => {
    return {
      get type() {
        return this[typeSymbol];
      },
      set type(value) {
        this[typeSymbol] = value;
      }
    };
  };
}
const myCar = makeCar();
myCar.type = 'SUV';
console.log(myCar.type);

Sinnvoll ist das im Vergleich zu einfachen Objekten nur, wenn im Getter oder Setter noch weiterer Code steht, z.B. eine Validierung im Setter vorgenommen wird.

Rey