Zum Inhalt springen

1.2 JavaScript-Grundkonstrukte

Zu Zen-Modus wechseln

Nach dieser Einheit kannst du:

  • Variablen mit const und let anlegen, Werte mit === vergleichen und Standardwerte mit ?? setzen.
  • Funktionen als Deklaration und als Arrow Function schreiben und die Unterschiede bei Kurzform und hoisting nennen.
  • Arrays mit map, filter und reduce verarbeiten und Objektliterale anlegen und lesen.

Wie kommt eine Musik-App zur Gesamtdauer deiner Playlist? Und warum springt die Lautstärke nach einem Neustart auf 50, obwohl du sie auf stumm gestellt hattest? Hinter beidem stecken JavaScript-Grundkonstrukte: eine Summe über ein Array und ein Standardwert, der mit dem falschen Operator gesetzt wurde.

flowchart LR
    accTitle: Zwei Alltagsfragen an eine Musik-App
    playlist["Playlist<br/>240, 180, 320, 150 s"] --> total["Gesamtdauer<br/>Summe 890 s"]
    volume["Lautstärke 0<br/>(stumm)"] --> wrong["Ersatz bei jedem<br/>falsy Wert: 50"]
    volume --> right["Ersatz nur bei<br/>null und undefined: 0"]

Abb. 1.4: Zwei Alltagsfragen, zwei Grundkonstrukte: eine Summe über ein Array und ein Standardwert, der die 0 behält oder verliert (eigene Darstellung).

Die meisten Konstrukte dieser Einheit kennst du aus anderen Sprachen, neu ist nur die Schreibweise. Aufpassen musst du an den Stellen, an denen JavaScript anders tickt: beim Vergleichen, bei Standardwerten und bei den Array-Methoden, die das Original verändern oder eben nicht.

  • Arrow Function: die kurze Schreibweise (x) => x * 2 für eine Funktion, meist einer Konstanten zugewiesen oder als Argument übergeben.
  • Hoisting: Eine function-Deklaration ist in ihrem ganzen Gültigkeitsbereich verwendbar, auch oberhalb der Zeile, in der sie steht.
  • Nullish Coalescing (??): liefert den Ersatzwert nur, wenn der linke Wert null oder undefined ist.
  • Objektliteral: ein Objekt, das direkt in geschweiften Klammern hingeschrieben wird, etwa { filename: "intro.mp4" }.

Die folgende Übersicht ist bewusst dicht; sie dient als Referenz und Wiederholung. Jedes Konstrukt gehört einmal selbst getippt und ausgeführt (Aufgabe 01).

let attempts = 0; // variable, reassignable
const MAX_ATTEMPTS = 3; // constant, cannot be reassigned
const name = "Ada"; // const is the default; let only when needed
typeof 42 // "number" (no int/float distinction!)
typeof "text" // "string"
typeof true // "boolean"
typeof undefined // "undefined"

Beispielprojekt: 01_typescript_examples/ex02_variables_and_types

Auffälligkeiten: Es gibt nur einen Zahlentyp number (Gleitkomma; 7 / 2 ist 3.5, Ganzzahldivision schreibt sich Math.floor(7 / 2)). Neben null (“bewusst leer”) existiert undefined (“nie befüllt”). Als Standard gilt const; let nur, wenn die Variable tatsächlich neu zugewiesen wird. var ist Alt-Syntax und tabu.

1 === 1 // true -> always use === and !==
1 == "1" // true?! -> == converts types; never use it
"" || "default" // "default"
value ?? "default" // "default" only if value is null/undefined

Beispielprojekt: 01_typescript_examples/ex03_comparisons

JavaScript wandelt bei == Typen still um; die Regeln dafür sind schwer zu merken und eine häufige Fehlerquelle. Deshalb vergleichst du immer mit === und !==. Vergisst du es trotzdem, meldet Biome die Stelle mit der Regel noDoubleEquals.

Der Operator ?? (Nullish Coalescing) liefert den Ersatzwert nur bei null/undefined, während || schon bei 0 oder "" zuschlägt. Für Standardwerte ist ?? fast immer der richtige. Konkret heißt das: Eine Lautstärke-Einstellung volume = 0 (stumm) wird mit volume || 50 still auf 50 gesetzt, mit volume ?? 50 bleibt sie korrekt bei 0. Solche Fehler fallen im Test oft nicht auf, weil man selten mit genau 0 testet.

Vier Werte für volume laufen durch volume || 50 und durch volume ?? 50. Mit || werden 0, der leere String, null und undefined alle zu 50. Mit ?? bleiben 0 und der leere String erhalten, nur null und undefined werden zu 50
Abb. 1.5: || ersetzt jeden falsy Wert, ?? nur null und undefined (eigene Darstellung).
Auflösung

settings.volume || 50 liefert 50, denn || ersetzt jeden falsy Wert, also auch die 0. settings.volume ?? 50 liefert 0, und settings.nickname ?? "Gast" liefert den leeren String "", weil ?? nur bei null und undefined zuschlägt. Richtig ist ??: Stumm bleibt stumm.

if (score >= 90) {
grade = 1;
} else if (score >= 75) {
grade = 2;
} else {
grade = 5;
}
for (const color of colors) { // iterate over elements
console.log(color);
}
while (attempts < MAX_ATTEMPTS) { attempts += 1; }
function rectangleArea(width, height) {
return width * height;
}

Beispielprojekt: 01_typescript_examples/ex04_control_flow

Blöcke werden mit geschweiften Klammern gebildet, die Einrückung ist Konvention (der Formatierer Biome erledigt sie). Namen schreiben sich in camelCase, Klassen in PascalCase, Konstanten in UPPER_CASE.

JavaScript kennt zwei Schreibweisen für Funktionen. Beide sind in Gebrauch, und die Wahl zwischen ihnen ist keine reine Geschmacksfrage - an einer Stelle verhalten sie sich unterschiedlich, und das kostet regelmäßig Zeit bei der Fehlersuche.

// 1. function declaration
function rectangleArea(width, height) {
return width * height;
}
// 2. arrow function, assigned to a constant
const double = (x) => x * 2; // implicit return, no braces
const half = (x) => { return x / 2; }; // with braces: return is mandatory
const greet = () => console.log("hi"); // no parameter: empty parentheses
const makePoint = (x, y) => ({ x, y }); // returning an object literal needs ( )

Beispielprojekt: 01_typescript_examples/ex05_function_syntax

Drei Unterschiede sind der Rede wert:

  • Kurzform: Ohne geschweifte Klammern gibt eine Arrow Function ihren Ausdruck automatisch zurück. Das macht sie als Argument für map, filter oder reduce lesbar - dort steht oft nur ein einziger Ausdruck.
  • Verfügbarkeit im Code: Eine function-Deklaration ist in ihrem gesamten Gültigkeitsbereich verwendbar, auch oberhalb ihrer Definition (hoisting). Eine Arrow Function ist eine Zuweisung an eine Konstante und existiert erst ab der Zeile, in der sie steht.
  • Bedeutung von this: Das ist der eigentliche Grund für die Unterscheidung. Weil this mit Objekten zu tun hat, bekommt es in Einheit 1.3 einen eigenen Abschnitt.
const durations = [240, 180, 320];
durations.push(150); // append
durations[0]; // 240
durations.length; // 4
durations.includes(320); // true
// the big three: transform, filter, aggregate
const doubled = durations.map((d) => d * 2);
const long = durations.filter((d) => d >= 180);
const total = durations.reduce((sum, d) => sum + d, 0);

Beispielprojekt: 01_typescript_examples/ex09_array_methods

map, filter und reduce nehmen Funktionen als Argumente und ersetzen einen Großteil der klassischen Schleifen. Sie sind der Alltagsstil in JavaScript-Projekten und tauchen ab dem React-Kapitel in praktisch jedem Codebeispiel auf; investiere hier Übungszeit.

Wichtig dabei: map und filter verändern das Original nicht, sondern liefern ein neues Array. durations hat nach den drei Zeilen oben also immer noch dieselben vier Einträge. push und sort dagegen verändern das bestehende Array - ein Unterschied, der im React-Kapitel entscheidend wird.

Das Array durations mit 240, 180, 320 und 150 geht an drei Methoden: map liefert 480, 360, 640, 300; filter mit d größer gleich 180 liefert 240, 180, 320; reduce liefert die Summe 890
Abb. 1.6: Drei Methoden, drei neue Ergebnisse; das Original bleibt unverändert (eigene Darstellung).

Wo begegnet dir das? Wie kommt eine Musik-App zur Gesamtdauer deiner Playlist? Eine Playlist ist ein Array von Songs, die Gesamtdauer eine Summe über alle Einträge, also ein reduce. Die Ansicht “nur Songs über drei Minuten” ist ein filter, und die Liste der Songtitel für die Anzeige ein map.

const clip = {
filename: "intro.mp4",
durationSeconds: 90,
tags: ["opener", "draft"],
};
clip.filename; // dot access
clip["filename"]; // bracket access
clip.fps = 25; // add a property

Beispielprojekt: 01_typescript_examples/ex10_objects

Das Objektliteral ist der universelle Datencontainer von JavaScript, vergleichbar mit Dictionaries oder Maps anderer Sprachen, nur mit Punktzugriff. JSON, das Datenformat des ganzen Jahres, ist nichts anderes als diese Syntax in Textform.

Auflösung

push und sort verändern das bestehende Array: Danach steht darin [ 150, 180, 240, 320 ]. map und filter lassen durations unverändert und liefern jeweils ein neues Array, das hier niemand aufhebt. Dass sort dabei richtig sortiert, ist Zufall: Alle Zahlen sind dreistellig, also stimmt die Textreihenfolge aus Einheit 1.1 mit der Zahlenreihenfolge überein.

  1. == statt ===: stille Typumwandlung mit absurden Ergebnissen; immer ===/!==. Biome meldet == mit der Regel noDoubleEquals.
  2. || statt ?? für Standardwerte: || ersetzt auch 0 und "". Eine Lautstärke 0 wird so still zu 50.
  3. const verhindert Neuzuweisung, nicht Veränderung: const list = [] erlaubt list.push(1), aber nicht list = [1].
  4. Nur ein Zahlentyp: 7 / 2 ist 3.5, und 0.1 + 0.2 === 0.3 ist false (Gleitkomma); Geldbeträge rechnet man in Cent.
  5. Geschweifte Klammern in der Arrow Function: (x) => { x * 2 } liefert undefined, weil mit Klammern ein return nötig ist.

Du kannst dir diese Einheit kostenlos mit der Vorlesefunktion deines Browsers oder Betriebssystems vorlesen lassen (etwa „Laut vorlesen” in Edge), ohne Konto und ohne Upload; die Codebeispiele liest du dabei am Bildschirm mit. Freiwillig kannst du mit Google NotebookLM (Google-Konto nötig) aus diesem öffentlichen Text eine gesprochene Zusammenfassung erzeugen, auch auf Deutsch.

Du kannst jetzt:

  • Variablen mit const und let anlegen, Werte mit === vergleichen und Standardwerte mit ?? setzen.
  • Funktionen als Deklaration und als Arrow Function schreiben und die Unterschiede bei Kurzform und hoisting nennen.
  • Arrays mit map, filter und reduce verarbeiten und Objektliterale anlegen und lesen.
  • Aufgabe 01 - TypeScript-Spickzettel, Stufe Wesentlich_vollständig (Spickzettel der Sprachkonstrukte)
  • Oliver Maurhart (MAO)
  • Michael Gabriel (GAM)

CC-BY-SA

https://qiz.at/rules