Konstruktoren in JavaScript [] (Konstruktoren in JavaScript), Lektion, Seite 723166
https://www.purl.org/stefan_ram/pub/konstruktoren_javascript (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram

Definition eines Konstruktors

Es ist aufwendig und fehlerträchtig, den Protoyp und die Felder zu jedem neuen Objekt hinzuzufügen, wie wir dies eben bei den Zählerobjekten gemacht haben.

Daher soll das Anlegen eines neuen Objektes der Objekttyps Zähler an einer Stelle zentralisiert werden.

Hierfür kommt zunächst einmal eine Funktion in Frage. Man spricht hier auch von einer Fabrikationsfunktion (factory function), weil sie Objekte fabriziert.

Es ist jedoch gebräuchlich, dafür einen Konstruktor zu verwenden, so daß wir uns nun erst einmal mit Konstruktoren beschäftigen.

Ein Konstruktor ist ebenfalls eine Funktion. Man nennt eine Funktion „Konstruktor“ wenn sie hinter »new« verwendet wird und dafür geschrieben wurde.

Bei Verwendung von new erzeugt ein Konstruktor eine neue Liste, welche innerhalb des Konstruktors »this« genannt wird.

function F(){ "use strict"; this.alpha = "Ada"; }
new F().alpha // "Ada" //
new F().constructor.name // "F" //

Wenn ein Objekt mit einem Konstruktor erzeugt wurde, so ist sein Prototyp normalerweise eine Prototyp-Variable des Konstruktors.

Object.getPrototypeOf( new F() )== F.prototype // true //

Die Prototyp-Variable des Konstruktors ist aber nicht mit dem Prototyp des Konstruktors gleichzusetzen!

Object.getPrototypeOf( F )== F.prototype // false //

Als Objekttyp eines Objektes kann man sich im allgemeinen den Namen des Konstruktors vorstellen. Aber nicht alle Objekte haben einen Konstruktor (wir hatten weiter oben Objekte ja ohne Konstruktor erzeugt).

Wir kennen schon einige vordefinierte Standardkonstruktoren von JavaScript, wie Number und String.

new String( "abc" ).constructor.name // "String" //

Die prototype-Variable des Konstruktors enthält eine constructor-Variable, welche normalerweise wieder der Konstruktor mit dieser prototyp-Variablen ist.

new String( "abc" ).constructor.prototype.constructor.name // "String" //

new String( "abc" ).constructor.prototype.constructor.prototype.constructor.name // "String" //

Man landet also immer wieder bei String! Deswegen kann man durch eine Abfolge von .constructor.prototype nicht die Prototyp-Kette hochlaufen. Dies geht nur mit Object.getPrototypeOf, welche den Prototyp eines Objekts ergibt (nicht den Inhalt seiner Prototyp-Variablen).

object.constructor = object.constructor.prototype.constructor

Konstruktoren schreibt man oft mit großem Anfangsbuchstaben (String, Number, F oben).

Definition von Feldern und Methoden mit Hilfe von Konstruktoren

Variablen eines Objekts nennt man auch dessen Felder.

Ein verbreitete und akzeptable Möglichkeit zum Anlegen von Objekten besteht darin, Felder, die in jedem Objekt als unabhängige Variable vorkommen sollen, im Konstruktor zu this hinzuzufügen, und Methoden, die für alle Objekte dieses Konstruktors gleich sein sollen, zum Prototyp des Konstruktors hinzuzufügen.

function Counter()
{ "use strict"; this.value = 0;
if( !Counter.prototype.inc )
Counter.prototype.inc =
function(){ return this.value++; }} // undefined //

let a = new Counter(); // undefined //

let b = new Counter(); // undefined //

a.inc() // 0 //
a.inc() // 1 //
a.inc() // 2 //

b.inc() // 1 //
b.inc() // 2 //
b.inc() // 3 //

Der Prototyp eines mit einem solchen Konstruktor erzeugten Objekts ist das Prototype-Feld des Konstruktors, und der Prototyp dieses Prototyps ist Object.prototyp, danach folgt nur noch null.

Object.getPrototypeOf( a )=== Counter.prototype // true //

Object.getPrototypeOf( Object.getPrototypeOf( a ))=== Object.prototype // true //

Object.getPrototypeOf( Object.getPrototypeOf( Object.getPrototypeOf( a )))=== null // true //

Konstruktorparameter

Wie eine Funktion kann ein Konstruktor auch Parameter haben.

function Counter( n )
{ "use strict"; this.value = n;
if( !Counter.prototype.inc )
Counter.prototype.inc =
function(){ return this.value++; }} // undefined //

let a = new Counter( 10 ); // undefined //

let b = new Counter( 20 ); // undefined //

a.inc() // 10 //
a.inc() // 11 //
a.inc() // 12 //

b.inc() // 20 //
b.inc() // 21 //
b.inc() // 22 //

Vergleich zwischen Objektliterale und Alternativen

Alternativen:

Im letzten Fall hat a aber keine constructor-Variable

Das folgende Beispiel zeigt eine einfach Möglichkeit zur Definition eines Zählers, wenn keine weiteren Zähler benötigt werden:

let c = { value: 0, inc: function(){ return this.value++; }} // undefined //

c.inc() // 0 //

c.inc() // 1 //

c.inc() // 2 //

Überschreiben des Prototyps

Man sollte aber nicht unbedingt einfach das Prototypfeld des Konstruktors überschreiben, weil dabei die Prototypkette des Konstruktors verloren gehen kann.

function Counter()
{ "use strict"; this.value = 0; } // undefined //

Counter.prototype =
{ inc: function(){ return this.value++; }} // Object { inc: Counter.prototype.inc() } //

let d = new Counter(); // undefined //

In den folgenden drei Zeilen ist aber noch alles in Ordnung. Das Problem zeigt sich erst in anderen Fällen.

Object.getPrototypeOf( d )=== Counter.prototype // true //

Object.getPrototypeOf( Object.getPrototypeOf( a ))=== Object.prototype // true //

Object.getPrototypeOf( Object.getPrototypeOf( Object.getPrototypeOf( a )))=== null // true //

Klassendeklarationen

In neueren JavaScript-Versionen wird es auch Klassendeklarationen geben, aber diese sind letztendlich nur eine andere Schreibweise für die hier schon vorgestellten Verfahren zum Anlegen von Objekten.

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723166 stefan_ram:723166 Konstruktoren in JavaScript Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723166, slrprddef723166, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/konstruktoren_javascript