Konstruktoren und this
Kurz gesagt: Der Konstruktor in JavaScript ist die Methode constructor, die bei new läuft und die Felder des Objekts über this füllt.
Problem
Kaffee für NaN €
Du erzeugst ein Produkt, genau wie in der letzten Lektion, und füllst die Felder Zeile für Zeile. Eine Zeile hast du vergessen:
const coffee = new Product();coffee.name = "Kaffee";coffee.quantity = 2;console.log(`${coffee.name}: ${coffee.price * coffee.quantity} €`);Kaffee: NaN €Der Kaffee kostet NaN € (Not a Number): Der Preis ist undefined, und undefined * 2 ist keine Zahl. JavaScript beschwert sich nicht. Je mehr Felder eine Klasse hat, desto leichter vergisst du eines. Und ein Produkt ohne Preis sollte es gar nicht geben können.
Die Idee
Konstruktor: ohne diese Daten kein Objekt
Eine Klasse kann sagen, was sie braucht, bevor du ein Objekt aus ihr erzeugen kannst. Dafür gibt es den Konstruktor: eine besondere Methode, die bei new läuft.
class Product { name; price; quantity;
constructor(name, price, quantity) { this.name = name; this.price = price; this.quantity = quantity; }}
const coffee = new Product("Kaffee", 7.50, 2);console.log(`${coffee.name}: ${coffee.price * coffee.quantity} €`);Kaffee: 15 €- Der Konstruktor heißt
constructor, in jeder Klasse. - Seine Parameter sind die Daten, ohne die ein Produkt nicht auskommt. Du übergibst sie in den Klammern von
new:new Product("Kaffee", 7.50, 2). - Er gibt nichts zurück.
newgibt das neue Objekt zurück.
Jetzt wird der Preis in derselben Zeile gesetzt, die das Produkt erzeugt, und du siehst, wenn er fehlt. Aber JavaScript zählt die Argumente nicht. Wenn du zwei statt drei übergibst, läuft das Programm, und die Stückzahl ist undefined:
const coffee = new Product("Kaffee", 7.50);undefinedKaffee: NaN €Die Anzahl der Argumente prüfst du also selbst. Wie ein Konstruktor ein schlechtes Objekt ablehnen kann, siehst du im Modul „Fehler und Exceptions“.
constructor(name, price, quantity) { this.name = name; this.price = price; this.quantity = quantity;}
const coffee = new Product("Kaffee", 7.50, 2);console.log(`${coffee.name}: ${coffee.price * coffee.quantity} €`);Schritt für Schritt, in Worten
- new legt ein neues Objekt an. Seine Felder sind noch undefined.
- Der Konstruktor läuft. Die Argumente werden in seine Parameter kopiert.
- this.name = name: vom Parameter in das Feld dieses Objekts.
- Dasselbe für Preis und Stückzahl.
- Der Konstruktor ist fertig, und die Parameter verschwinden. coffee bekommt einen Pfeil auf das fertige Objekt.
- Das Objekt kommt schon gefüllt aus new, deshalb ist der Preis nicht undefined.
Die Idee
this: das Feld dieses Objekts
Im Konstruktor gibt es zwei Dinge namens name: den Parameter und das Feld. Der bloße Name ist der Parameter. Für das Feld schreibst du this.name.
constructor(name, price, quantity) { this.name = name; this.price = price; this.quantity = quantity;}this ist das Objekt, das gerade entsteht. this.name = name; bedeutet „speichere den Parameter name im Feld name dieses Objekts“.
In JavaScript ist this. Pflicht, sobald du ein Feld anfasst. Ohne es ist name immer der Parameter (oder eine andere Variable), nie das Feld.
Probier es aus
Finde den Fehler
Wähle die Zeile mit dem Fehler.
name = name; speichert den Parameter in sich selbst. Das Feld bleibt undefined. Du brauchst this.name = name;. JavaScript meldet keinen Fehler, deshalb ist so ein Fehler schwer zu finden.
Die Idee
Und new Product() aus der letzten Lektion?
In der letzten Lektion gab es keinen Konstruktor, und new Product() hat funktioniert: Wenn du keinen Konstruktor schreibst, fügt JavaScript einen leeren hinzu. Sobald du einen eigenen schreibst, ruft jedes new ihn auf.
JavaScript prüft aber nicht, ob alle Argumente übergeben werden. new Product() funktioniert weiterhin, und die Felder bleiben undefined:
const empty = new Product();Product { name: undefined, price: undefined, quantity: undefined }console.log auf einem Objekt zeigt seine Felder. Hier siehst du, dass keines davon gefüllt ist. In Java und C# lässt sich so eine Zeile nicht kompilieren, in JavaScript liegt es an dir: Übergib alle Argumente.
Die Idee
Eine Standard-Stückzahl
Die meisten Produkte im Warenkorb kommen einzeln. Jedes Mal 1 zu tippen wird lästig.
In JavaScript kann eine Klasse nur einen constructor haben. Statt eines zweiten Konstruktors bekommt der Parameter einen Standardwert: Wenn du keine Stückzahl übergibst, ist sie 1.
constructor(name, price, quantity = 1) { this.name = name; this.price = price; this.quantity = quantity;}quantity = 1 bedeutet „wenn keine Stückzahl übergeben wird, nimm 1“. Setz so einen Parameter ans Ende: Dann kannst du ihn beim Aufruf einfach weglassen.
Genauer, für Neugierige
Ein zweiter constructor in der Klasse ist ein Fehler, und das Programm startet gar nicht erst:
SyntaxError: A class may only have one constructorDer Vorteil eines einzigen Konstruktors: Wenn du morgen eine Prüfung des Preises hinzufügst, steht sie an einer Stelle.
Probier es aus
Welcher Konstruktor?
Was gibt das Programm aus?
class Product { name; price; quantity;
constructor(name, price, quantity = 1) { this.name = name; this.price = price; this.quantity = quantity; }}
const bread = new Product("Brot", 1.20);const milk = new Product("Milch", 2.10, 3);console.log(bread.quantity, milk.quantity);new Product("Brot", 1.20) hat keine Stückzahl, also nimmt quantity den Standardwert 1. Für die Milch wird die Stückzahl übergeben: 3.Probier es aus
Wie heißt der Konstruktor?
Was steht in der Lücke?
class Book {
title;
author;
(title, author) {
this.title = title;
this.author = author;
}
}constructor: So heißt der Konstruktor in jeder Klasse.Übung
Objekte, die vollständig entstehen
Löse die Aufgaben in deinem Editor. Jede Klasse bekommt einen Konstruktor mit Parametern für alle ihre Felder.
1. Person. Eine Klasse Person mit Name und Alter. Erzeuge zwei Personen und gib ihre Daten aus.
Maria, 34 JahrePeter, 19 Jahre2. Tier. Eine Klasse Animal mit Art und Alter. Erzeuge eine 3 Jahre alte Katze und einen 7 Jahre alten Hund.
Art: Katze, Alter: 3Art: Hund, Alter: 73. Tanzschritt. Eine Klasse DanceMove mit Name und Dauer in Sekunden. In der Lektion „Instanzmethoden“ lernt der Schritt, sich selbst „auszuführen“.
moonwalk: 5 Sek.Weitere Aufgaben
- Ein Buch mit Konstruktor. Schreib
Bookaus der letzten Lektion mit einem Konstruktorconstructor(title, author)neu. Wie viele Zeilen sparst du in dem Code unter der Klasse? -
Ein Produkt mit Standard-Stückzahl.
Productmitquantity = 1, wie in der Lektion. Leg ein Array[new Product("Brot", 1.20, 2), new Product("Kaffee", 7.50)]an und gib von jedem Name und Stückzahl aus: „Brot x2“, „Kaffee x1“. - Buchung. Eine Klasse
Bookingmit dem Namen des Gastes, der Anzahl der Nächte und dem Preis pro Nacht. Gib aus, was der Aufenthalt kostet: Für 3 Nächte zu 85 € sind das 255 €.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Arrays · Funktionen · Parameter und return · Klassen und Objekte
- Geht weiter in: Instanzmethoden · Kapselung · static: was alle Objekte teilen · Vererbung
- Aufgaben zum Thema: Klassen und Objekte