1unitedpower: Die Vererbung

Beitrag lesen

Würden wir hingegen das Schlüsselwort new bei unserem Funktionsaufruf vergessen, dann hätten wir unter Anderem ein paar neue globale Variablen produziert…

Dagegen beschützt dich der strict-Mode.

Aber als Funktionsobjekt besitzt unser Konstruktor ja auch noch eine Eigenschaft namens prototype, bei der es sich ebenso um ein (beinahe) leeres Object handelt, welchem wir ebenfalls Eigenschaften und Methoden zuweisen können:

var Kaefer = function (name) {
  this.name = name;
  this.typ = 'Ungeziefer';
  this.farbe = 'braun';
};

Kaefer.prototype.beruf = false;

Kaefer.prototype.gesundheit = 0;

Kaefer.prototype.bewerfen = function ( ) {
  this.gesundheit -= Math.ceil(Math.random( ) * 10);
};

Wenn wir nun also Kaefer als Konstruktor aufrufen, dann verfügt gregor nicht nur über die direkt in der Funktion deklarierten Eigenschaften, sondern ebenso über die Eigenschaften und Methoden, welche von uns in Kaefer.prototype hinterlegt wurden:

var gregor = new Kaefer('Gregor');

gregor.bewerfen( );
gregor.bewerfen( );

var status = gregor.gesundheit; // z.B. -7  :-(

Zwischen den direkt im Konstruktor angelegten Objekteigenschaften und denjenigen, welche wir im Prototypobjekt des Konstruktors spezifiziert haben, besteht allerdings ein Unterschied:

var farbe = gregor.hasOwnProperty('farbe'); // true

var beruf = gregor.hasOwnProperty('beruf'); // false

Bei den Eigenschaften, welche wir für das Prototypobjekt der Konstruktorfunktion angelegt hatten, handelt es sich also nicht um eigene Eigenschaften unseres Instanzobjektes, sondern um geerbte.

Interessant in dem Zusammenhang ist, dass die Methode bewerfen bei ihrem ersten Aufruf eine neue Eigenschaft direkt auf der Instanz erzeugt, und nicht die Eigenschaft des Prototyps verändert:

var gregor = new Kaefer('gregor');
console.assert(gregor.hasOwnProperty('gesundheit') === false, 'Gesundheit ist eine direkte Eigenschaft von gregor');
gregor.bewerfen();
console.assert(gregor.hasOwnProperty('gesundheit') === true, 'Gesundheit ist keine direkte Eigenschaft von gregor');

Die Meldungen sind etwas konfus, weil sie an der Stelle Fehlermeldungen darstellen und keine Erläuterungen. Sie beschreiben also den negativen Fall, dass die Assertions fehlschlagen, nicht den positiven Fall (hier fallen beide Assertions positiv aus)

Eine unmittelbare Auswirkung ist, dass die bewerfen-Methode die Zustände anderer Kaefer-Instanzen unverändert lässt.

Nachdem wir dies also vollbracht haben, verfügt gregor nun über eine ganze Reihe an Eigenschaften, von denen lediglich name, typ und farbe eigene Eigenschaften sind, welche in der Konstruktorfunktion spezifiziert wurden, während der gesamte Rest über die Prototypenkette geerbt wurde.

Bis auf solche Eigenschaften, die durch Duck typing eben noch zur Laufzeit hinzukommen können, wie im oberen Fall geschildert. gesundheit ist zunächst keine eigene Eigeschaft von Kaefer-Instanzen, wird aber dazu, sobald die bewerfen-Methode aufgerufen wird.