Start / Cheat Sheets

Cheat Sheet

JavaScript in der Praxis — Cheat Sheet

Stand: · JavaScript Grundlagen & Modernes ECMAScript

JavaScriptNode.jsAsyncTesting

Der Spickzettel zur zweiten Hälfte des Seminars JavaScript Grundlagen & Modernes ECMAScript: alles, was um die Sprache herum zum Arbeiten gehört. Die Sprache selbst — Typen, Datenstrukturen, Closures — steht auf dem ersten Blatt: JavaScript Sprachkern.

Maßgeblich bleibt die Node.js-Dokumentation für Node-eigene APIs und MDN für die Sprache. Dieses Blatt trifft die Auswahl und ersetzt weder Referenz noch Seminar.

Debuggen: die Schrittbefehle

BefehlWirkung
Step Overführt die Zeile aus, ohne in Funktionen zu springen
Step Intospringt in den Aufruf hinein
Step Outbeendet die aktuelle Funktion, zurück zum Aufrufer
Continueläuft bis zum nächsten Haltepunkt

Der Aufrufstapel zeigt den Weg bis zur aktuellen Zeile — bei tiefen Fehlern die wichtigste Ansicht, und die, die am häufigsten ignoriert wird. Der Haltepunkt gehört vor die interessante Zeile, nicht dahinter.

Modul: Problemlösung und Debugging

Testen: Begriffe und Werkzeuge

BegriffBedeutung
Testfallein konkretes Szenario mit erwartetem Ergebnis
Testsuiteeine Gruppe zusammengehörender Testfälle
Zusicherungdie Prüfung, ob etwas dem Erwarteten entspricht
AbdeckungAnteil des Codes, den die Tests ausgeführt haben
WerkzeugEinordnung
Jestseit Jahren verbreitet, in vielen Bestandsprojekten
Vitestin modernen Projekten üblich, besonders mit Vite
node:testin Node.js eingebaut, ohne zusätzliche Abhängigkeit

Die Schreibweise ist nahezu identisch — describe, it, expect:

import { describe, it, expect } from "vitest";

describe("istBefuellt", () => {
  it("lehnt eine leere Zeichenkette ab", () => {
    expect(istBefuellt("")).toBe(false);
  });
});

Hohe Abdeckung mit schwachen Zusicherungen beweist nichts; sie ist kein Qualitätsziel für sich.

Modul: JavaScript testen

Asynchron: die drei Muster

MusterIdee
Callbackeine Funktion, die später aufgerufen wird
Promiseein Platzhalter für ein Ergebnis, das noch aussteht
async/awaitasynchroner Code, der sich wie synchroner liest
Zustand eines PromiseBedeutung
ausstehenddie Operation läuft noch
erfülltsie war erfolgreich, ein Wert liegt vor
abgelehntsie ist gescheitert, ein Fehler liegt vor

Alle drei Muster existieren nebeneinander — im Bestand trifft man auf jedes. Eine async-Funktion liefert immer ein Promise, auch wenn im Rumpf nichts Asynchrones passiert. Synchrones try/catch greift nur zusammen mit await.

Modul: Asynchrones JavaScript

Welcher Promise-Kombinator wann

AufrufVerhalten
Promise.allalle müssen gelingen, bricht beim ersten Fehler ab
Promise.allSettledwartet auf alle, meldet je Vorgang den Ausgang
Promise.anyder erste Erfolg genügt, Fehler werden ignoriert
Promise.raceder erste entschiedene Vorgang zählt, egal wie
Promise.trystartet eine Kette aus möglicherweise synchronem Code

Die Reihenfolge der Ergebnisse bei all entspricht der Eingabe, nicht der Fertigstellung. Unabhängige Aufrufe gehören parallel gestartet statt einzeln awaitet — aufeinander aufbauende dagegen nicht.

HTTP: fetch prüft nichts von allein

const antwort = await fetch(url);
if (!antwort.ok) throw new Error(`HTTP ${antwort.status}`);
const daten = await antwort.json();

fetch lehnt nur bei Netzwerkfehlern ab — ein 404 kommt als ganz normale Antwort an. Wer auf einen Fehler wartet, wartet vergebens. Die Struktur der Antwort ist ebenfalls nicht garantiert und gehört geprüft.

Modul: Promises, HTTP-Anfragen und Events

Module: Exportarten und Pfade

ArtPassend, wenn …
benanntdas Modul mehrere verwandte Funktionen anbietet
Standarddas Modul genau einen Hauptwert hat
beides gemischtmöglich, aber selten hilfreich

Benannte Exporte sind der Normalfall — im Importierenden ist sofort sichtbar, was benutzt wird. Für ES-Module gilt: "type": "module" in der package.json, die Dateiendung im Importpfad ist nötig, relative Pfade beginnen mit einem Punkt, und eingebaute Module tragen das Präfix node:. JSON lässt sich direkt importieren — mit Attribut:

import beete from "./beete.json" with { type: "json" };

Modul: Module, Pakete und Projektstruktur

Projektdateien: was wohin gehört

Datei oder OrdnerUmgang
package.jsonin die Versionsverwaltung
package-lock.jsonebenfalls — sie macht Installationen reproduzierbar
node_modules/nicht einchecken, nicht von Hand ändern

Auf einem anderen Rechner stellt npm install den Stand aus beiden Dateien wieder her. Geschnitten wird nach Zuständigkeit, nicht nach Dateityp: eine Datei für den Dateizugriff, eine für die Prüfung, eine für die Darstellung, eine für die Fachlogik — und ein Einstiegspunkt, der nur koordiniert.

Kommandozeilenargumente nicht von Hand zählen, sondern benannt auslesen:

import { parseArgs } from "node:util";
const { values } = parseArgs({
  options: { name: { type: "string", short: "n" } },
});

Modul: Module, Pakete und Projektstruktur

Daten: Herkunft, Datenbank, SQL

HerkunftPassend, wenn …
statischer Importdie Daten fester Bestandteil des Projekts sind
Datei zur Laufzeitder Pfad variabel ist oder sich der Inhalt ändert
HTTP-Antwortdie Daten von einem anderen System kommen

Am Ende entstehen in allen drei Fällen gewöhnliche JavaScript-Objekte — nur Herkunft und Fehlerquellen unterscheiden sich.

DatenbankJavaScript
Spalten in Unterstrich-SchreibweiseEigenschaften in camelCase
Wahrheitswerte als 0 und 1true und false
Zeilen als ErgebnisObjekte im Programm

Die Umsetzung zwischen beiden Welten gehört an eine Stelle. Und Abfragen werden parametrisiert, nie zusammengesetzt:

const nachArt = db.prepare("SELECT * FROM beete WHERE art = ?");
const treffer = nachArt.all(eingabe);

Modul: Dateizugriff, Datenaustausch und Datenbanken

Sauberer Code: wer wofür zuständig ist

WerkzeugAufgabe
ESLintmeldet mögliche Fehler und Projektregeln
Prettiervereinheitlicht Einrückung, Umbrüche, Anführungszeichen
Engineakzeptiert oder verwirft — mehr nicht

Der Linter sagt „das sieht nach einem Fehler aus”, der Formatierer beendet die Stildiskussion. Beim Lesen fremden Codes: bei der package.json anfangen, die Skripte mitlesen, den Datenfluss Datei für Datei verfolgen — und alte Muster nicht ungefragt modernisieren.

Modul: Sauberer Code und fremden Code lesen

Typische Fallen

  • Ein 404 ist kein Fehler für fetch. Ohne antwort.ok läuft der Fehlerfall als Erfolg weiter.
  • await vergessen — und man arbeitet mit einem Promise statt mit dem Wert.
  • catch weggelassen erzeugt eine unbehandelte Ablehnung.
  • finally läuft auch im Fehlerfall — es ist kein Erfolgspfad.
  • Kein Zeitlimit lässt eine hängende Anfrage nie enden.
  • readFile ohne Kodierungsangabe liefert einen Puffer statt Text.
  • Relative Pfade hängen davon ab, aus welchem Ordner gestartet wurde — besser über import.meta.url aufbauen.
  • SQL aus Zeichenketten zusammensetzen, auch nur ein einziges Mal: das ist die Einladung zur SQL-Injection. Eine Eingabeprüfung ersetzt das nicht.
  • node_modules einchecken oder die package-lock.json weglassen — beides fällt erst auf dem zweiten Rechner auf.
  • ES-Module und CommonJS in einer Datei mischen oder das node:-Präfix weglassen.
  • Ereignisnamen vertippen: Es passiert schlicht nichts, keine Meldung.
  • Testdateien so benennen, dass das Werkzeug sie nicht findet — oder das Testskript in der package.json vergessen.
  • Nur den Normalfall testen und den Fall 0 auslassen, weil er wie ein leerer Wert aussieht.
  • Linter-Meldungen pauschal abschalten, statt sie zu beheben.

Zum Seminar JavaScript Grundlagen & Modernes ECMAScript