Kurz: Guter JavaScript-Code ist lesbar, vorhersagbar und vermeidet bekannte Stolperfallen.
Teil des Kurses JavaScript
Kapitel 38 von 40 im Kurs JavaScript. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.
Guter JavaScript-Code ist lesbar, vorhersagbar und vermeidet bekannte Stolperfallen.
Lesbarkeit
- Sprechende Namen:
anzahlKundenstattn,istAktivstattflag. Funktionen sind Verben (berechneSumme), Booleans lesen sich wie Fragen (hatZugriff) - Kleine Funktionen: eine Funktion, eine Aufgabe
- Frühe Rückgabe statt tiefer Verschachtelung
- Keine magischen Zahlen:
const MAX_VERSUCHE = 3statt einer losen3 - Kommentare erklären das Warum, nicht das Was
// Schlecht
function f(a) { if (a) { if (a.length > 0) { if (a[0] > 5) { return true; } } } return false; }
// Besser
const MIN_WERT = 5;
function ersterWertIstGross(liste) {
if (!liste?.length) return false;
return liste[0] > MIN_WERT;
}
console.log(f([9]), ersterWertIstGross([9]), ersterWertIstGross([]));Ausgabe:
true true falseEmpfohlene Gewohnheiten
| Tue | Statt |
|---|---|
const / let | var |
=== | == |
| Template-Strings | Text mit + zusammenkleben |
map/filter/reduce | Schleifen, die Arrays aufbauen |
?. und ?? | lange &&-Ketten |
async/await | verschachtelte Callbacks |
Module (import) | globale Variablen |
Häufige Fallen
1. Typumwandlung
console.log("5" + 1, "5" - 1, [] + {}, [1, 2] + [3]);
console.log(0.1 + 0.2 === 0.3, 9007199254740993);
console.log([10, 9, 1].sort());
console.log(parseInt("08"), parseInt("0x1f"), Number(""), Number(" "), Number(null), Number(undefined));Ausgabe:
51 4 [object Object] 1,23
false 9007199254740992
[ 1, 10, 9 ]
8 31 0 0 0 NaN2. this verloren
const objekt = { name: "Mia", sagHallo() { return "Hallo " + this?.name; } };
const lose = objekt.sagHallo;
console.log(objekt.sagHallo(), "|", lose());
console.log(lose.call({ name: "Tom" }), "|", lose.bind(objekt)());Ausgabe:
Hallo Mia | Hallo undefined
Hallo Tom | Hallo Mia3. Veränderliche geteilte Daten
const a = { liste: [1, 2] };
const b = { ...a }; // flache Kopie: liste wird geteilt!
b.liste.push(3);
console.log(a.liste);
const c = structuredClone(a);
c.liste.push(4);
console.log(a.liste, c.liste);
function f(x = []) { x.push(1); return x; } // neue Liste pro Aufruf (anders als in Python)
console.log(f(), f());Ausgabe:
[ 1, 2, 3 ]
[ 1, 2, 3 ] [ 1, 2, 3, 4 ]
[ 1 ] [ 1 ]4. Vergessene await
const hole = async () => 42;
async function main() {
const falsch = hole(); // Promise statt Wert
const richtig = await hole();
console.log(typeof falsch, falsch instanceof Promise, richtig);
[1, 2, 3].forEach(async x => { await null; }); // forEach wartet nicht
}
main();Ausgabe:
object true 425. Gleichheit von Objekten
console.log({} === {}, [] === [], [1] == 1, NaN === NaN, Object.is(NaN, NaN));
console.log(JSON.stringify({ a: 1 }) === JSON.stringify({ a: 1 }));
console.log(structuredClone({ a: [1] }).a !== undefined);Ausgabe:
false false true false true
true
true6. Schleifen und Closures mit var
Siehe Kapitel Gültigkeitsbereich: Nutze let/const in Schleifen.
7. Unveränderliches bevorzugen
Funktionen, die ihre Eingaben nicht verändern, sind leichter zu verstehen. Nutze toSorted, toReversed, Spread und structuredClone, statt Parameter zu mutieren.
Sicherheit im Web-Code
- XSS: Setze nie ungeprüfte Nutzereingaben per
innerHTMLein; benutzetextContentoder baue Elemente mitcreateElement - Keine Geheimnisse im Frontend: API-Schlüssel und Passwörter im Browsercode sind für alle sichtbar
- Eingaben nie vertrauen: Prüfe sie am Server, auch wenn der Browser sie schon geprüft hat
- eval() und new Function() nicht für Nutzereingaben verwenden
- Abhängigkeiten aktuell halten (
npm audit)
Leistung
- Nur messen, was langsam ist, nicht raten (
console.time, Performance-Tab) - DOM-Zugriffe bündeln, nicht in jeder Schleife
innerHTML +=ausführen - Große Listen mit Virtualisierung oder Paginierung anzeigen
- Ereignisse mit Debounce/Throttle drosseln
- Ressourcen nachladen, wenn sie gebraucht werden (
import(),loading="lazy")
Barrierefreiheit
- Native Elemente (
button,a,input) stattdivmit Klick-Listener - Alle Funktionen per Tastatur erreichbar machen
- Dynamische Änderungen mit
aria-liveoderrole="status"ankündigen - Fokus beim Öffnen und Schließen von Dialogen bewusst setzen
Merke
- Sprechende Namen, kleine Funktionen, frühe Rückgabe
const/let,===, Template-Strings,async/await- Fallen: Typumwandlung,
this, flache Kopien, vergesseneawait, Objektgleichheit - Eingaben nie ungeprüft in
innerHTML; keine Geheimnisse im Frontend - Erst messen, dann optimieren
Übungsaufgabe
Gehe ein älteres Skript durch und ersetze var, == und verschachtelte Bedingungen durch moderne Muster. Schreibe zu jeder Änderung einen Satz, warum.
Quiz zur Selbstkontrolle
== 1 wahr?
- == wandelt Typen vorher um (richtig)
- Arrays sind Zahlen
- Es ist ein Fehler
- Weil [1] ein Objekt ist
Wie vermeidest du XSS beim Einfügen von Text?
- textContent statt innerHTML (richtig)
- eval()
- document.write()
- Mit Großbuchstaben
Was vermeidest du im Browsercode?
- Geheime Schlüssel (richtig)
- const
- Funktionen
- Kommentare
Weiter im Kurs
Zurück: Werkzeuge: Linter, Formatter, TypeScript
Weiter: Projekt: Eine Aufgabenliste
Alle Kapitel: JavaScript im Überblick