Der Konstruktor
Mit festen Anfangswerten beginnt jedes neue Monster als Goblin mit 30 Leben, und du musst seine Felder nach new ändern. Praktischer ist es, gleich zu sagen, was du willst: new Monster("Wolf", 25). Dafür ist der Konstruktor da:
class Monster {
name: string;
leben: number;
constructor(name: string, leben: number) {
this.name = name;
this.leben = leben;
}
}
const wolf = new Monster("Wolf", 25);
const troll = new Monster("Troll", 80);
console.log(wolf);
console.log(troll);Das gibt aus:
Monster { name: "Wolf", leben: 25 }
Monster { name: "Troll", leben: 80 }Der Konstruktor ist eine besondere Funktion in der Klasse mit dem Namen constructor. Du rufst ihn nie selbst auf: new ruft ihn jedes Mal auf, wenn es ein Objekt erzeugt, und die Argumente von new Monster("Wolf", 25) gehen in seine Parameter. Die Parameter haben Typen wie in jeder Funktion, also prüft TypeScript die Argumente von new: new Monster("Wolf") ergibt Expected 2 arguments, but got 1. (TS2554), und new Monster(25, "Wolf") ist TS2345.
Was ist this? Im Konstruktor ist this das neue Objekt, das gerade erzeugt wird. this.name = name; bedeutet: „Setze das Feld name des neuen Objekts auf den Wert des Parameters name.“ Beide Seiten heißen gleich, das ist üblich, aber es sind zwei verschiedene Dinge: this.name ist das Feld, das einfache name der Parameter.
Also macht new Monster("Wolf", 25) Folgendes:
- Es erzeugt ein neues, leeres Objekt der Klasse
Monster. - Es setzt die Felder, die einen Anfangswert haben.
- Es führt den Konstruktor aus, wobei
thisdas neue Objekt ist, sodass der Konstruktor den Rest ausfüllen kann. - Es gibt dir das fertige Objekt.
Die Felder name und leben haben jetzt keine Anfangswerte, und das ist in Ordnung: TypeScript prüft, dass der Konstruktor jedem von ihnen einen Wert gibt. Ein Feld kann auch einen Anfangswert behalten und im Konstruktor gar nicht vorkommen, wie stufe: number = 1;.
Typischer Fehler: this. in this.name = name; vergessen. Dann weist name = name; den Parameter nur sich selbst zu, und das Feld bleibt leer. TypeScript bemerkt es:
class Monster {
name: string;
leben: number;
constructor(name: string, leben: number) {
name = name;
this.leben = leben;
}
}TypeScript meldet:
main.ts(2,5): error TS2564: Property 'name' has no initializer and is not definitely assigned in the constructor.Eine Anmerkung für später. In anderem TypeScript-Code wirst du eine kürzere Schreibweise sehen: constructor(public name: string) {} deklariert das Feld und setzt es in einem Zug. Sie heißt Parameter Property, und diese Seite erlaubt sie nicht: Du bekämest This syntax is not allowed when 'erasableSyntaxOnly' is enabled. (TS1294), dieselbe Meldung wie bei enum in der Lektion über Unions und Narrowing. Eine Parameter Property ist nicht einfach JavaScript mit Typen: TypeScript muss zusätzlichen Code dafür erzeugen, und Werkzeuge, die nur die Typen entfernen, können das nicht. Schreibe also die Felder und this.name = name;, wie oben.
So schreibst du es:
Anweisungen
- 1
Gib
Heldeinen Konstruktor mit zwei Parametern,name: stringundheldenKlasse: HeldenKlasse, der die FeldernameundheldenKlassesetzt. Entferne die Anfangswerte dieser beiden Felder (stufebehält seine1). TypeScript meldet dann die Zeilen mitnew Held(): Gib ihnen ihre Argumente,new Held("Kira", "Waldläuferin")undnew Held("Bruno", "Krieger"), und lösche die beiden Zeilen, die Bruno nachträglich geändert haben. Das Programm gibt dasselbe aus wie vorher. - 2
Lena, die Magierin, stößt zur Gruppe. Erzeuge
lenamit dem Konstruktor und gib sie mithilfe ihrer Felder so aus:Lena, die Magierin, Stufe 1