Einheit 05

JavaScript-Grundlagen I

Webentwicklung & Agentic Coding
Sommersemester 2026

Begrüßung. Rückblick auf HTML und CSS — die Studierenden haben bisher Struktur und Darstellung gelernt. Heute kommt die dritte Säule hinzu: JavaScript für Verhalten und Interaktivität. Agentic-Coding-Fokus dieser Einheit: Code Literacy (CL) und Code Review (RV).

JavaScript: Die dritte Säule des Web

Jede Webseite besteht aus drei Technologien:

TechnologieAufgabeAnalogie
HTMLStruktur & InhaltSkelett / Rohbau
CSSDarstellung & LayoutFarbe / Einrichtung
JavaScriptVerhalten & InteraktivitätElektrik / Haustechnik

JavaScript macht Webseiten lebendig:

  • Auf Benutzer-Aktionen reagieren (Klicks, Eingaben, Scrollen)
  • Inhalte dynamisch ändern, ohne die Seite neu zu laden
  • Daten verarbeiten und validieren (z.B. Formulare prüfen)
  • Mit Servern kommunizieren (Daten laden, APIs ansprechen)

JavaScript ist die einzige Programmiersprache, die nativ in jedem Browser läuft.

Die Studierenden kennen bereits HTML und CSS. JavaScript bringt nun die Dynamik. Betonen: JavaScript ist eine echte Programmiersprache — im Gegensatz zu HTML (Auszeichnungssprache) und CSS (Stylesheet-Sprache). Das ist ein qualitativer Sprung.

JavaScript einbinden

1. Inline im HTML (nicht empfohlen):

<button onclick="alert('Hallo!')">Klick</button>

2. Internes Script-Tag:

<script>
  console.log('Hallo aus dem Script-Tag!');
</script>

3. Externes Skript (Best Practice):

<script src="skript.js" defer></script>

Das defer-Attribut:

  • Ohne defer: Browser stoppt HTML-Parsing, lädt und führt JS sofort aus
  • Mit defer: JS wird geladen, aber erst nach dem HTML-Parsing ausgeführt
  • Empfehlung: Immer defer verwenden oder <script> am Ende von <body> platzieren
Externes Skript ist die sauberste Lösung — Trennung von Struktur und Verhalten. defer ist wichtig, weil das Script sonst auf DOM-Elemente zugreift, die noch nicht existieren. Parallele zu CSS: So wie wir CSS in eine separate Datei auslagern, machen wir es auch mit JS.

Die Browser-Konsole

Die Konsole ist Ihr wichtigstes Werkzeug zum Testen und Debuggen:

Öffnen: F12 → Tab „Console" (oder Strg+Umschalt+J)

// Ausgabe in der Konsole
console.log('Hallo Welt!');
console.log(42);
console.log('Name:', 'Schuchardt');

// Warnung und Fehler
console.warn('Achtung: Wert fehlt');
console.error('Fehler beim Laden');

// Objekte schön formatiert
console.table({name: 'Hugo', jahr: 1842});

Direkt in der Konsole tippen:

> 2 + 3
5
> 'Hugo' + ' ' + 'Schuchardt'
"Hugo Schuchardt"
> typeof 42
"number"

Tipp: Die Konsole ist ein Spielplatz — probieren Sie alles direkt aus!

LIVE DEMO: Browser-Konsole öffnen und gemeinsam Befehle eintippen. Die Studierenden sollen sofort mitmachen. Das senkt die Hemmschwelle enorm. console.log ist die wichtigste Debugging-Methode — wird uns die ganze LV begleiten.

Variablen: let und const

Variablen sind benannte Speicherplätze für Werte:

// const = Konstante (Wert ändert sich nicht)
const name = 'Schuchardt';
const geburtsjahr = 1842;
const istLinguist = true;

// let = Variable (Wert kann sich ändern)
let briefZaehler = 0;
briefZaehler = briefZaehler + 1; // jetzt 1
briefZaehler = briefZaehler + 1; // jetzt 2

// FEHLER: const kann nicht neu zugewiesen werden
const stadt = 'Graz';
stadt = 'Wien'; // TypeError!

Wann was verwenden?

  • const: Standard-Wahl. Verwenden Sie const, wenn sich der Wert nicht ändern soll.
  • let: Nur wenn sich der Wert im Programm ändern muss (Zähler, Status-Variablen).
  • var: Veraltet — nicht mehr verwenden!

Namenskonvention: camelCase — briefTitel, absenderName, empfangsJahr

Wichtig: const ist der Standard, let nur bei Bedarf. var nie verwenden (Scoping-Probleme). Analogie: const ist wie ein Etikett, das fest auf einer Box klebt. let ist wie ein Etikett, das man umkleben kann. CamelCase erklären — erster Buchstabe klein, dann jedes neue Wort groß.

Datentypen: String, Number, Boolean

JavaScript hat verschiedene primitive Datentypen:

// String — Text in Anführungszeichen
const titel = 'Brief an Otto Benndorf';
const stadt = "Graz";

// Number — Ganze Zahlen und Dezimalzahlen
const jahr = 1879;
const laenge = 3.5;

// Boolean — Wahrheitswert (true/false)
const istPubliziert = true;
const hatAntwort = false;

// Spezialwerte
const unbekannt = null;      // bewusst leer
let nichtDefiniert;           // undefined (kein Wert zugewiesen)

Typ herausfinden mit typeof:

console.log(typeof titel);          // "string"
console.log(typeof jahr);           // "number"
console.log(typeof istPubliziert);  // "boolean"
console.log(typeof unbekannt);      // "object" (JS-Bug!)
console.log(typeof nichtDefiniert); // "undefined"
typeof null === "object" ist ein bekannter JavaScript-Fehler aus der Urzeit der Sprache. Das verwirrt Anfänger — kurz erwähnen, nicht zu lange aufhalten. Für DH: Strings sind besonders wichtig (Texte, Titel, Namen). Numbers für Jahreszahlen, Zähler etc.

Datentypen: Array und Object

Array — eine geordnete Liste von Werten:

const sprachen = ['Deutsch', 'Romanisch', 'Baskisch'];
console.log(sprachen[0]);     // "Deutsch" (Index beginnt bei 0!)
console.log(sprachen.length); // 3

// Neues Element hinzufügen
sprachen.push('Kreolisch');
console.log(sprachen.length); // 4

Object — eine Sammlung von Schlüssel-Wert-Paaren:

const brief = {
  titel: 'Brief an Karl Vossler',
  absender: 'Hugo Schuchardt',
  empfaenger: 'Karl Vossler',
  jahr: 1904,
  ort: 'Graz'
};

console.log(brief.titel);      // "Brief an Karl Vossler"
console.log(brief['jahr']);     // 1904
console.log(Object.keys(brief)); // ["titel","absender","empfaenger","jahr","ort"]

Arrays und Objects sind die wichtigsten Datenstrukturen in JavaScript!

Arrays: Index startet bei 0 — das ist für Anfänger verwirrend, mehrfach betonen. Objects: Wie ein Wörterbuch oder eine Karteikarte. Schlüssel → Wert. DH-Bezug: Metadaten zu einem Brief sind ein typisches Object. Eine Sammlung von Briefen ist ein Array von Objects.

Operatoren

Arithmetische Operatoren:

const summe = 1842 + 85;   // 1927 (Todesjahr)
const diff = 1927 - 1842;  // 85 (Lebensalter)
const produkt = 12 * 5;    // 60
const quotient = 100 / 4;  // 25
const rest = 17 % 5;       // 2 (Modulo)

Vergleichsoperatoren:

console.log(5 === 5);     // true (strikt gleich)
console.log(5 === '5');   // false (verschiedene Typen!)
console.log(5 !== 3);     // true (strikt ungleich)
console.log(1879 > 1900); // false
console.log(1879 <= 1900); // true

Logische Operatoren:

const jahr = 1879;
console.log(jahr > 1800 && jahr < 1900); // true (UND)
console.log(jahr < 1800 || jahr > 1900); // false (ODER)
console.log(!(jahr === 1879));           // false (NICHT)

Immer === statt == verwenden! Strikter Vergleich prüft auch den Typ.

=== vs == ist eine häufige Fehlerquelle. == wandelt Typen um ("5" == 5 ist true!). === prüft Wert UND Typ. Immer === verwenden — das ist die sichere Variante. Logische Operatoren: && = UND, || = ODER, ! = NICHT. Modulo (%) ist nützlich für z.B. "jede zweite Zeile anders formatieren".

Template Literals

Template Literals verwenden Backticks (`) statt Anführungszeichen:

const name = 'Hugo Schuchardt';
const jahr = 1842;
const ort = 'Graz';

// Alte Methode: String-Verkettung mit +
const text1 = name + ', geboren ' + jahr + ' in ' + ort;

// Moderne Methode: Template Literals mit ${...}
const text2 = `${name}, geboren ${jahr} in ${ort}`;

// Beide ergeben: "Hugo Schuchardt, geboren 1842 in Graz"

Vorteile von Template Literals:

  • Variablen direkt im String mit ${...} einbetten
  • Ausdrücke berechnen: `Alter: ${1927 - 1842} Jahre`
  • Mehrzeilige Strings ohne \n:
const html = `
  <div class="brief">
    <h2>${brief.titel}</h2>
    <p>Von: ${brief.absender}</p>
  </div>
`;

Template Literals sind besonders nützlich, wenn wir HTML-Code in JavaScript erzeugen!

Template Literals sind ein Gamechanger für die Arbeit mit Strings. Besonders beim Erzeugen von HTML-Fragmenten im DOM. Backtick-Taste zeigen — auf deutscher Tastatur: Shift + Akzent-Taste (neben Backspace). Die Studierenden werden Template Literals ständig brauchen.

Bedingte Ausführung: if / else

Code nur ausführen, wenn eine Bedingung erfüllt ist:

const jahr = 1879;

if (jahr > 1880) {
  console.log('Nach 1880 verfasst');
} else if (jahr === 1880) {
  console.log('Genau 1880 verfasst');
} else {
  console.log('Vor 1880 verfasst');
}
// Ausgabe: "Vor 1880 verfasst"

Praxisbeispiel — Brief-Kategorisierung:

const brief = { jahr: 1904, sprache: 'Deutsch', seiten: 3 };

if (brief.seiten > 5) {
  console.log('Langer Brief');
} else if (brief.seiten > 2) {
  console.log('Mittlerer Brief');
} else {
  console.log('Kurzer Brief');
}

// Kombination mit logischen Operatoren
if (brief.jahr > 1900 && brief.sprache === 'Deutsch') {
  console.log('Deutscher Brief aus dem 20. Jh.');
}
if/else ist die grundlegendste Kontrollstruktur. Die Studierenden kennen das Konzept vielleicht aus dem Alltag: "Wenn es regnet, nehme ich den Regenschirm, sonst nicht." Klammern { } nicht vergessen — häufiger Anfängerfehler. Code-Einrückung betonen: Macht den Code leserlich.

Schleifen: for und for...of

for-Schleife — klassisch mit Zähler:

const briefe = [
  'Brief an Benndorf',
  'Brief an Vossler',
  'Brief an Meringer'
];

for (let i = 0; i < briefe.length; i++) {
  console.log(`${i + 1}. ${briefe[i]}`);
}
// 1. Brief an Benndorf
// 2. Brief an Vossler
// 3. Brief an Meringer

for...of-Schleife — moderner und lesbarer:

for (const brief of briefe) {
  console.log(brief);
}
// Brief an Benndorf
// Brief an Vossler
// Brief an Meringer

Wann was verwenden?

  • for...of: Wenn Sie nur die Werte brauchen (häufigster Fall)
  • for mit Index: Wenn Sie den Index brauchen oder rückwärts iterieren wollen
for...of ist die moderne und leserlichere Variante — bevorzugt verwenden. Die klassische for-Schleife ist wichtig zu kennen, weil LLMs sie oft generieren. Häufiger Fehler: i <= briefe.length statt i < briefe.length (Off-by-one-Error). DH-Bezug: Über eine Liste von Briefen, Personen oder Orten iterieren.

Funktionen

Funktionen fassen wiederverwendbaren Code in einem Block zusammen:

// Funktionsdeklaration
function begruessung(name) {
  return `Hallo ${name}, willkommen im Archiv!`;
}

// Aufruf
const text = begruessung('Hugo Schuchardt');
console.log(text);
// "Hallo Hugo Schuchardt, willkommen im Archiv!"

Funktion mit mehreren Parametern:

function briefInfo(absender, empfaenger, jahr) {
  return `Brief von ${absender} an ${empfaenger} (${jahr})`;
}

console.log(briefInfo('Schuchardt', 'Vossler', 1904));
// "Brief von Schuchardt an Vossler (1904)"

Funktion ohne Rückgabewert:

function zeigeWarnung(meldung) {
  console.warn(`Warnung: ${meldung}`);
  // kein return — gibt implizit undefined zurück
}

zeigeWarnung('Brief nicht gefunden');
Funktionen sind essentiell — Code-Wiederverwendung ist das Fundament guter Programmierung. Analogie: Eine Funktion ist wie ein Rezept. Parameter sind die Zutaten, return ist das fertige Gericht. return beendet die Funktion und gibt einen Wert zurück.

Arrow Functions

Kurzschreibweise für Funktionen mit dem Pfeil-Operator =>:

// Klassische Funktion
function begruessung(name) {
  return `Hallo ${name}`;
}

// Arrow Function (gleiche Funktion)
const begruessung = (name) => {
  return `Hallo ${name}`;
};

// Kurzform: Bei einem Ausdruck kann man { } und return weglassen
const begruessung = (name) => `Hallo ${name}`;

// Bei einem Parameter kann man auch ( ) weglassen
const begruessung = name => `Hallo ${name}`;

Arrow Functions in der Praxis:

const jahre = [1879, 1892, 1904, 1910];

// Array filtern: nur Jahre nach 1900
const nachNeunzehnhundert = jahre.filter(j => j > 1900);
console.log(nachNeunzehnhundert); // [1904, 1910]

// Array transformieren: Alter berechnen (von 1927 aus)
const alter = jahre.map(j => 1927 - j);
console.log(alter); // [48, 35, 23, 17]
Arrow Functions sind modernes JavaScript — LLMs generieren sie häufig. Die Studierenden müssen sie lesen können, auch wenn sie selbst die klassische Form bevorzugen. filter() und map() sind Array-Methoden, die Arrow Functions besonders nützlich machen. Nicht zu viel auf einmal — die Kurzschreibweisen kommen mit der Übung.

Das DOM: Document Object Model

Das DOM ist die Baumstruktur, die der Browser aus dem HTML erzeugt:

HTML-Code:                        DOM-Baum:

<html>                            document
  <body>                             └─ html
    <h1>Titel</h1>                       └─ body
    <p>Text</p>                              ├─ h1
  </body>                                    │   └─ "Titel"
</html>                                      └─ p
                                                  └─ "Text"

Wichtige Begriffe:

  • Document: Das gesamte HTML-Dokument als Objekt
  • Node (Knoten): Jedes Element, jeder Text, jedes Attribut im Baum
  • Element: Ein HTML-Tag (z.B. <h1>, <p>, <div>)
  • Parent/Child: Eltern- und Kind-Beziehungen im Baum

JavaScript greift über das DOM auf die HTML-Seite zu und kann sie verändern!

Das DOM ist die Brücke zwischen JavaScript und der sichtbaren Webseite. Analogie: Das DOM ist wie ein Stammbaum — jedes Element hat Eltern und Kinder. In den DevTools (Elements-Tab) sieht man den DOM-Baum live. Wenn JavaScript HTML verändert, ändert sich der DOM, und der Browser aktualisiert die Anzeige.

DOM-Zugriff: Elemente auswählen

Um ein Element zu verändern, müssen wir es zuerst finden:

// Per CSS-Selektor (moderne Methode — empfohlen!)
const titel = document.querySelector('h1');
const absatz = document.querySelector('.brief-text');
const box = document.querySelector('#info-box');

// Alle passenden Elemente finden
const alleParagraphen = document.querySelectorAll('p');
console.log(alleParagraphen.length); // z.B. 5

// Ältere Methoden (funktionieren, aber querySelector ist flexibler)
const element = document.getElementById('info-box');
const elemente = document.getElementsByClassName('brief');

querySelector vs. querySelectorAll:

  • querySelector() — gibt das erste passende Element zurück
  • querySelectorAll() — gibt alle passenden Elemente als NodeList zurück
// Über alle gefundenen Elemente iterieren
const items = document.querySelectorAll('li');
for (const item of items) {
  console.log(item.textContent);
}
querySelector nutzt CSS-Selektoren — die kennen die Studierenden bereits aus der CSS-Einheit! Das ist ein großer Vorteil: Selektoren müssen nicht neu gelernt werden. getElementById ist die alte Methode, funktioniert aber immer noch und ist etwas schneller. Wichtig: querySelectorAll gibt eine NodeList zurück, kein Array (aber for...of funktioniert).

DOM-Manipulation: Inhalte und Klassen ändern

Inhalte ändern:

const titel = document.querySelector('h1');
titel.textContent = 'Neuer Titel';        // Nur Text
titel.innerHTML = '<em>Neuer</em> Titel';  // Mit HTML

CSS-Klassen steuern:

const box = document.querySelector('.brief');
box.classList.add('hervorgehoben');     // Klasse hinzufügen
box.classList.remove('versteckt');      // Klasse entfernen
box.classList.toggle('aktiv');          // Klasse umschalten
console.log(box.classList.contains('aktiv')); // true/false

Styles direkt setzen:

titel.style.color = 'darkred';
titel.style.fontSize = '2rem';
titel.style.backgroundColor = '#f0f0f0';

Neue Elemente erstellen:

const neuerAbsatz = document.createElement('p');
neuerAbsatz.textContent = 'Dieser Absatz wurde mit JS erstellt.';
document.querySelector('main').appendChild(neuerAbsatz);
textContent vs. innerHTML: textContent ist sicherer (kein XSS-Risiko), innerHTML erlaubt HTML. classList ist die moderne Methode, um CSS-Klassen zu steuern. Toggle ist besonders praktisch. style.property: CamelCase statt Bindestrich (fontSize statt font-size). Best Practice: Lieber Klassen hinzufügen/entfernen als Styles direkt setzen.

Event-Handling: Auf Benutzer reagieren

Events sind Aktionen, auf die unser Code reagiert:

const button = document.querySelector('#mein-button');

button.addEventListener('click', function() {
  console.log('Button wurde geklickt!');
  alert('Hallo!');
});

// Kurzform mit Arrow Function
button.addEventListener('click', () => {
  console.log('Klick!');
});

Wichtige Events:

EventWann?Typisches Element
clickElement angeklicktButton, Link, Bild
inputWert in Eingabefeld ändert sichinput, textarea
submitFormular abgeschicktform
mouseoverMaus über ElementJedes Element
keydownTaste gedrücktinput, document
addEventListener ist die moderne Methode — nicht onclick-Attribute im HTML verwenden. Wichtig: Die Funktion wird nicht sofort ausgeführt, sondern erst beim Event (Callback-Konzept). Das Event-Objekt (e) erwähnen, aber nicht zu tief einsteigen (kommt in der nächsten Einheit).

Praxis: Button klicken, Inhalt ändern

Ein vollständiges Beispiel — HTML und JavaScript zusammen:

<!-- HTML -->
<h1 id="titel">Hugo Schuchardt Archiv</h1>
<p id="info">Klicken Sie auf einen Button.</p>

<button id="btn-bio">Biografie zeigen</button>
<button id="btn-briefe">Briefe zeigen</button>
// JavaScript
const info = document.querySelector('#info');
const btnBio = document.querySelector('#btn-bio');
const btnBriefe = document.querySelector('#btn-briefe');

btnBio.addEventListener('click', () => {
  info.textContent = 'Hugo Schuchardt (1842-1927) war ein '
    + 'österreichischer Sprachwissenschaftler in Graz.';
  info.style.color = 'darkgreen';
});

btnBriefe.addEventListener('click', () => {
  info.innerHTML = 'Schuchardt hinterließ über '
    + '<strong>13.000 Briefe</strong> an Fachkollegen '
    + 'in ganz Europa.';
  info.style.color = 'darkblue';
});

Dieses Muster — Element finden, Event binden, DOM ändern — verwenden Sie ständig!

LIVE DEMO: Dieses Beispiel gemeinsam aufbauen und testen. Die drei Schritte betonen: 1) Element finden, 2) Event-Listener hinzufügen, 3) Aktion ausführen. Zeigen, wie sich der Text und die Farbe bei jedem Klick ändern.

XML im Browser parsen

JavaScript kann XML direkt im Browser parsen — ohne externe Bibliotheken:

const xmlString = `
  <brief>
    <absender>Hugo Schuchardt</absender>
    <empfaenger>Karl Vossler</empfaenger>
    <datum>1904-01-03</datum>
    <text>Verehrter Herr Kollege!</text>
  </brief>
`;

// XML-String in ein DOM-Dokument umwandeln
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'application/xml');

// Daten extrahieren — wie bei HTML querySelector!
const absender = xmlDoc.querySelector('absender').textContent;
const datum = xmlDoc.querySelector('datum').textContent;

console.log(absender); // "Hugo Schuchardt"
console.log(datum);    // "1904-01-03"

DOMParser erzeugt aus einem XML-String einen Baum — genau wie der Browser aus HTML!

DOMParser ist eine eingebaute Browser-API — kein Import nötig. Der geparste XML-Baum funktioniert ähnlich wie der HTML-DOM: querySelector, textContent etc. Das ist besonders relevant für DH-Studierende: TEI-XML, das sie kennen, kann direkt im Browser verarbeitet werden.

TEI-XML einlesen und verarbeiten

Schritt 1: TEI-XML laden (hier als String, alternativ mit fetch):

const teiXml = `
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Brief an Karl Vossler</title>
      </titleStmt>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <opener>
        <dateline>Graz, 3. Jänner 1904</dateline>
        <salute>Verehrter Herr Kollege!</salute>
      </opener>
      <p>Empfangen Sie meinen Dank...</p>
      <closer>
        <signed>Ihr Hugo Schuchardt</signed>
      </closer>
    </body>
  </text>
</TEI>`;

Schritt 2: Parsen und Daten extrahieren:

const parser = new DOMParser();
const doc = parser.parseFromString(teiXml, 'application/xml');

const titel = doc.querySelector('title').textContent;
const datum = doc.querySelector('dateline').textContent;
const gruss = doc.querySelector('salute').textContent;
const text = doc.querySelector('body p').textContent;
const signatur = doc.querySelector('signed').textContent;
TEI-XML ist den DH-Studierenden vertraut — sie sehen jetzt, wie man es programmatisch verarbeitet. Hinweis: Bei echtem TEI muss man den Namespace beachten (querySelector funktioniert trotzdem oft). Alternativ zu String-Konstanten: fetch('brief.xml') für externe Dateien.

Live-Demo: Brief-TEI als HTML anzeigen

Schritt 3: Extrahierte Daten als HTML rendern:

// Zielbereich im HTML
const ausgabe = document.querySelector('#brief-ausgabe');

// HTML zusammenbauen mit Template Literals
ausgabe.innerHTML = `
  <article class="brief">
    <h2>${titel}</h2>
    <p class="brief-datum">${datum}</p>
    <p class="brief-gruss">${gruss}</p>
    <div class="brief-text">
      <p>${text}</p>
    </div>
    <p class="brief-signatur">${signatur}</p>
  </article>
`;

Der vollständige Ablauf:

  1. Quelle: TEI-XML (String oder Datei)
  2. Parsen: DOMParser → XML-DOM
  3. Extrahieren: querySelector → Einzelne Werte
  4. Rendern: Template Literal → innerHTML

Dieses Muster — Daten laden, verarbeiten, darstellen — ist das Fundament jeder Web-Anwendung!

LIVE DEMO: Das komplette Beispiel von Folie 20 und 21 zusammenführen und live zeigen. Zeigen, wie aus dem XML-Text eine hübsche HTML-Darstellung entsteht. Das ist ein sehr motivierendes Ergebnis für DH-Studierende!

Agentic Coding: Code lesen und verstehen (CL)

Code Literacy (CL) bedeutet: generierten Code lesen und verstehen können.

Strategie zum Code-Lesen:

  1. Überblick: Was macht der Code insgesamt? (Kommentare lesen)
  2. Variablen: Welche Daten werden gespeichert? Was bedeuten die Namen?
  3. Kontrollfluss: Welche Bedingungen, Schleifen, Funktionsaufrufe gibt es?
  4. DOM-Zugriffe: Welche HTML-Elemente werden verändert?
  5. Events: Auf welche Benutzeraktionen reagiert der Code?

Prompt für Code Literacy:

Erkläre mir diesen JavaScript-Code Zeile für Zeile.
Was macht jede Zeile? Welche Konzepte werden verwendet?
Verwende einfache Sprache für JavaScript-Anfänger.

Sie müssen Code nicht auswendig schreiben können — aber Sie müssen ihn lesen und verstehen können!

Code Literacy ist der wichtigste Skill für Agentic Coding. LLMs schreiben den Code, aber die Studierenden müssen verstehen, was er tut. Vergleich: Man muss kein Autor sein, um Texte kritisch lesen zu können. Übung: Code-Schnipsel zeigen und die Studierenden erklären lassen, was sie sehen.

Code Review: Generierten JS-Code prüfen (RV)

Code Review (RV) bedeutet: generierten Code systematisch auf Fehler prüfen.

Häufige Fehler in LLM-generiertem JavaScript:

  • Falsche Selektoren: ID oder Klasse existiert nicht im HTML
  • Timing-Probleme: Script läuft bevor das DOM geladen ist (fehlendes defer)
  • Typfehler: == statt ===, String statt Number
  • Undefinierte Variablen: Tippfehler im Variablennamen
  • Veraltete Syntax: var statt let/const
  • innerHTML mit Nutzerdaten: XSS-Sicherheitslücke

Review-Checkliste:

  1. Läuft der Code ohne Fehler in der Konsole?
  2. Stimmen die Selektoren mit dem HTML überein?
  3. Werden const/let korrekt verwendet?
  4. Sind die Variablennamen verständlich?
  5. Ist der Code kommentiert?
Code Review ist eine professionelle Praxis — auch bei erfahrenen Entwicklern. Die Studierenden sollen die Checkliste bei jeder Übung anwenden. LIVE DEMO: Einen absichtlich fehlerhaften Code zeigen und gemeinsam die Fehler finden.

Debugging: Fehler finden und beheben

Die Konsole ist Ihr bester Freund beim Debugging:

// 1. Werte überprüfen
console.log('Titel:', titel);
console.log('Typ:', typeof titel);

// 2. Zwischen-Ergebnisse prüfen
const elemente = document.querySelectorAll('.brief');
console.log('Gefundene Elemente:', elemente.length);

// 3. Objekte inspizieren
console.log('Brief-Objekt:', brief);
console.table(briefe); // Schöne Tabelle in der Konsole

Browser DevTools — wichtige Features:

  • Console-Tab: Fehlermeldungen lesen (rot = Error, gelb = Warning)
  • Elements-Tab: DOM live inspizieren und prüfen, ob JS-Änderungen wirken
  • Sources-Tab: Breakpoints setzen — Code Zeile für Zeile durchgehen
  • Network-Tab: Prüfen, ob Dateien (JS, XML) korrekt geladen werden

Typische Fehlermeldungen:

// "Cannot read property 'textContent' of null"
// → querySelector hat kein Element gefunden! Selektor prüfen.

// "x is not defined"
// → Variable existiert nicht. Tippfehler? Scope-Problem?

// "x is not a function"
// → Falscher Typ. Variable ist kein Function-Objekt.
Debugging ist eine Kernkompetenz. Fehler gehören zum Programmieren dazu. Die drei häufigsten Fehler bei Anfängern betonen: 1. Element nicht gefunden (null), 2. Tippfehler, 3. Timing (DOM nicht bereit). LIVE DEMO: Einen Fehler einbauen, die Konsole zeigen, gemeinsam beheben.

Zusammenfassung und Übungsvorschau

Was haben wir heute gelernt?

  • JavaScript ist die dritte Säule des Web (Verhalten + Interaktivität)
  • Variablen: const (Standard) und let (veränderbar)
  • Datentypen: String, Number, Boolean, Array, Object
  • Operatoren: +, -, ===, !==, &&, ||
  • Kontrollstrukturen: if/else, for, for...of
  • Funktionen: klassisch und Arrow Functions
  • DOM: querySelector, textContent, classList, addEventListener
  • XML parsen: DOMParser für TEI-XML im Browser
  • Agentic Coding: Code Literacy (CL) und Code Review (RV)

Übungen:

  • Konsolen-Experiment — Variablen und Datentypen üben
  • DOM-Detektiv — HTML-Seite mit JavaScript manipulieren
  • TEI-zu-HTML — TEI-Brief parsen und als HTML darstellen
  • CSV-Parser — Korrespondenz-Daten als Tabelle rendern

Fragen? Dann viel Spaß bei den Übungen!

Zusammenfassung zügig durchgehen. Offene Fragen klären. Auf die Übungen hinweisen — die erste Übung ist bewusst niederschwellig. Nächste Einheit: JavaScript-Grundlagen II (Fetch API, JSON, fortgeschrittenes DOM). Ermutigen: JavaScript fühlt sich am Anfang schwieriger an als HTML/CSS — das ist normal!
F = Fullscreen | N = Notizen | ← → Navigation