🏛️Klassen, Module und Fehler
Klassen bündeln Daten und Verhalten, Module teilen Code in Dateien auf, und Fehlerbehandlung sorgt dafür, dass ein Problem nicht das ganze Programm abreißt.
🧬Klassen
class, Felder, Getter, static
1class Punkt {2 x; y; // öffentliche Felder3 static ursprung = new Punkt(0, 0);4 constructor(x, y) { this.x = x; this.y = y; }5 get laenge() { return Math.hypot(this.x, this.y); }6 toString() { return `(${this.x}|${this.y})`; }7}8const p = new Punkt(3, 4);9console.log(p.laenge, String(p), String(Punkt.ursprung));10console.log(typeof Punkt);
Klassen sind „syntaktischer Zucker“ über Konstruktorfunktionen und Prototypen – typeof liefert function.
Private Felder und Methoden (#)
1class Tresor {2 #code;3 constructor(code) { this.#code = code; }4 #pruefe(v) { return v === this.#code; }5 oeffnen(v) { return this.#pruefe(v) ? "offen" : "zu"; }6 static istTresor(o) { return #code in o; }7}8const t = new Tresor("beispiel-passwort");9console.log(t.oeffnen("falsch"), t.oeffnen("beispiel-passwort"));10console.log(Object.keys(t), Tresor.istTresor(t));
#-Felder (ES2022) sind wirklich privat – von außen nicht lesbar, auch nicht über Object.keys.
extends und super
1class Tier {2 constructor(name) { this.name = name; }3 laut() { return "…"; }4 vorstellen() { return `${this.name} sagt ${this.laut()}`; }5}6class Hund extends Tier {7 constructor(name) { super(name); this.art = "Hund"; }8 laut() { return "Wuff"; }9}10const h = new Hund("Bello");11console.log(h.vorstellen(), h instanceof Tier);
Im Konstruktor einer abgeleiteten Klasse muss super() vor dem ersten Zugriff auf this stehen.
Was steckt dahinter?
h ──[[Prototype]]──▶ Hund.prototype ──▶ Tier.prototype ──▶ Object.prototype ──▶ null │ │ laut() │ laut() │ toString() … │ name: "Bello" │ constructor │ vorstellen() │ art: "Hund"
Methoden liegen nicht im Objekt selbst, sondern auf dem Prototyp. h.vorstellen() wird entlang der Kette gesucht; this.laut() findet zuerst Hund.prototype.laut.
Prototypenkette interaktiv →📦Module: import und export
1// mathe.js2export const PI = 3.14159;3export function flaeche(r) {4 return PI * r * r;5}6export default class Rechner { /* … */ }
1// main.js2import Rechner, { flaeche, PI as kreiszahl } from "./mathe.js";3import * as mathe from "./mathe.js";45console.log(flaeche(2), kreiszahl, mathe.PI);67// dynamisch (lädt erst bei Bedarf, liefert ein Promise):8const { flaeche: f } = await import("./mathe.js");
Eigenschaften von Modulen
- Benannte Exporte (beliebig viele) und höchstens einen Default-Export.
- Imports sind Live-Bindungen: ändert das exportierende Modul den Wert, sieht der Importeur ihn.
- Imports werden gehoistet und vor dem Code ausgewertet; jedes Modul läuft nur einmal, egal wie oft es importiert wird.
- Top-Level-await (ES2022) ist nur in Modulen erlaubt.
- Import-Attribute (ES2025):
import d from "./d.json" with { type: "json" }
1<!-- im Browser -->2<script type="module" src="main.js"></script>
require() und module.exports. Mit "type": "module" in der package.json oder der Endung .mjs nutzt Node ES-Module.🧯Fehlerbehandlung
try / catch / finally
1function teile(a, b) {2 if (b === 0) throw new RangeError("Division durch 0");3 return a / b;4}5try {6 console.log(teile(6, 3));7 console.log(teile(1, 0));8 console.log("wird nicht erreicht");9} catch (e) {10 console.log(e.name, "–", e.message);11} finally {12 console.log("finally läuft immer");13}
Eigene Fehlerklasse und cause
1class ValidierungsFehler extends Error {2 constructor(feld, options) {3 super(`Ungültig: ${feld}`, options);4 this.name = "ValidierungsFehler";5 }6}7try {8 try { JSON.parse("{kaputt"); }9 catch (e) { throw new ValidierungsFehler("email", { cause: e }); }10} catch (e) {11 console.log(e.name, e.message, e instanceof Error);12 console.log("Ursache:", e.cause.name);13}
Mit der Option cause (ES2022) lässt sich die ursprüngliche Ausnahme anhängen.
| Fehlertyp | typischer Auslöser |
|---|---|
| ReferenceError | Variable existiert nicht oder steht noch in der TDZ |
| TypeError | undefined.x, Aufruf eines Nicht-Funktions-Werts, Zuweisung an const |
| SyntaxError | Tippfehler im Code, ungültiges JSON bei JSON.parse |
| RangeError | ungültige Array-Länge, zu tiefe Rekursion, toFixed(101) |
| AggregateError | mehrere Fehler auf einmal, z. B. von Promise.any |
Fehler in asynchronem Code (Promises, async/await) funktionieren etwas anders – siehe Asynchron → Fehler.