Objekt in Objekt wird nicht angezeigt
bearbeitet von
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.
~~~JavaScript
// 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`.
~~~JavaScript
// 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.
~~~JavaScript
// 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.
~~~JavaScript
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.
~~~JavaScript
// 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` dort 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.
~~~JavaScript
// 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
Objekt in Objekt wird nicht angezeigt
bearbeitet von
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.
~~~JavaScript
// direct call expression
motorAusgeben();
~~~
Bei einem normalen Funktionsaufruf zeigt `this` auf `window`, oder `undefined`, wenn das Skript im Strict Mode ausgeführt wird.
~~~JavaScript
// 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.
~~~JavaScript
// 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.
~~~JavaScript
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.
~~~JavaScript
// 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` dort zu definieren hingegen schon.
Die Funktion `motorAusgeben` ist offenbar 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.
~~~JavaScript
// 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