Hallo Felix
Ich bin mir jetzt nicht sicher, ob in Deiner Variante innerhalb von
motorAusgeben
das Schlüsselwortthis
auf dasMotor
-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