Orlok: Objekt in Objekt wird nicht angezeigt

Beitrag lesen

Hallo Felix

Ich bin mir jetzt nicht sicher, ob in Deiner Variante innerhalb von motorAusgeben das Schlüsselwort this auf das Motor-Objekt verweist, oder nicht.

Worauf this innerhalb von motorAusgeben zeigt hängt von der Art des Aufrufs ab, nicht davon, wie die Funktion definiert wurde.

// direct call expression

motorAusgeben();

Bei einem normalen Funktionsaufruf zeigt this auf window, oder undefined, wenn das Skript im Strict Mode ausgeführt wird. In einem Modul ist this bei einem gewöhnlichen Aufruf standardmäßig undefined.

// via member expression

const motor = new Motor;

motor.motorAusgeben();

Wird eine Funktion über einen Elementausdruck als Methode eines Objektes aufgerufen, dann enthält this eine Referenz auf eben dieses Objekt. Das entspricht dem Folgenden Aufruf mit call, bei dem die Referenz explizit übergeben wird.

// provide function context explicitly

const motor = new Motor;

motorAusgeben.call(motor);

Dass im vorliegenden Programm Object.prototype.toString überschrieben wird ändert an all dem nichts. Eine Methode ist nur eine Dateneigenschaft und der Wert eine Referenz auf die in diesem Fall außerhalb des Konstruktors definierte Funktion.

function Motor() {
  this.toString = motorAusgeben;
}

// trigger implicit toString call

document.body.append(new Motor);

Wird das Objekt in einen Kontext gebracht in der ein String erwartet wird, dann wird nach einer Methode toString gesucht, erst auf dem Objekt selbst und dann in seiner Prototypenkette.

In diesem Fall wird bereits auf der Instanz eine entsprechende Eigenschaft gefunden, die Referenz aufgelöst und dann die Funktion motorAusgeben im Kontext der Instanz aufgerufen.

// Delegate method to prototype

Motor.prototype.toString = function () { /* ... * / };

Die Methode unter dem Eigenschaftsnamen motorAusgeben zu definieren so wie du es vorgeschlagen hast wäre im Hinblick auf das offenbar gewünschte Verhalten nicht sinnvoll, die Methode unter dem Namen toString auf dem Prototyp zu definieren hingegen schon.

Die Funktion motorAusgeben ist inhaltlich eng mit der Klasse Motor verknüpft, folglich ist es sinnvoll sie auch auf Motor.prototype zu definieren um diese Verbindung auch nach außen sichtbar zu machen.

// same as Motor.prototype.toString.call(motor);

const motor = new Motor;

motor.toString();

Bei einem Aufruf auf einer Instanz von Motor wird toString nun nicht mehr über das Objekt selbst sondern über seinen Prototypen referenziert. Die Kontextvariable this zeigt in diesem Fall wie du schon sagtest dennoch auf die Instanz.

Viele Grüße,

Orlok