Skip to content

JavaScript Deep Dive

Vorwort

Du hast HTML und CSS gelernt und kannst ansprechende Webseiten erstellen. Aber dir fällt vielleicht auf: Buttons reagieren nicht, Formulare lassen sich nicht absenden, die Webseite wirkt wie ein „statisches" Bild.

Genau dafür brauchen wir JavaScript – es erweckt die Webseite zum Leben. Ein Klick auf einen Button öffnet ein Menü, Texteingaben liefern Echtzeitsuche, beim Scrollen werden weitere Inhalte geladen … all diese Interaktionen basieren auf JavaScript.

Beim Vibecoding schreibt die KI den Großteil des Codes für dich. Aber du solltest zumindest verstehen, was der Code tut – sonst merkst du nicht, wenn die KI etwas falsch macht. Nach diesem Artikel wirst du:

  • Verstehen, was der KI-generierte Code tut
  • Erkennen, wo Probleme im Code liegen
  • Der KI mit klaren Worten sagen können, was sie ändern soll

Was lernst du in diesem Artikel?

KapitelInhaltWas du danach kannst
Kapitel 1Was ist JavaScriptSeine Rolle im Web verstehen
Kapitel 2Daten & VariablenWissen, wie Programme Daten speichern und nutzen
Kapitel 3Funktionen & LogikBedingungen, Schleifen und Wiederverwendung verstehen
Kapitel 4DOM & EventsVerstehen, wie Code Webseiten steuert und auf Nutzeraktionen reagiert
Kapitel 5PraxistippsKI-Code lesen und Fehlermeldungen beschreiben

Jedes Kapitel beginnt mit „Code erkennen" – du musst ihn nicht selbst schreiben können. Wenn du auf unbekannten Code stößt, schlag jederzeit hier nach.


1. Was ist JavaScript?

🤔 Kernfrage

Warum brauchen Webseiten JavaScript? HTML und CSS liefern bereits Inhalt und Stil – warum noch eine neue Sprache lernen?

1.1 Von „statischen Seiten" zu „dynamischen Anwendungen"

📄 Webseite ohne JavaScript

  • Feste Inhalte, keine Interaktion
  • Buttons reagieren nicht
  • Formulare lassen sich nicht absenden
  • Die Seite aktualisiert sich nicht von selbst

Wie ein gedrucktes Plakat – nur zum Anschauen

🚀 Webseite mit JavaScript

  • Klick auf Button öffnet ein Menü
  • Texteingabe liefert Echtzeitsuche
  • Scrollen lädt automatisch weitere Inhalte
  • Daten werden in Echtzeit aktualisiert

Wie eine echte Anwendung

Das Zusammenspiel der drei Technologien in einem Satz:

TechnologieAnalogieFunktion
HTMLSkelettDefiniert Struktur und Inhalt der Webseite
CSSHautDefiniert Aussehen und Stil der Webseite
JavaScriptMuskeln und NervensystemMacht die Webseite reaktionsfähig, interaktiv und intelligent

1.2 Warum brauchst du auch beim Vibecoding JavaScript-Kenntnisse?

Stolperfalle für JS-Anfänger

Ein Entwickler, der gerade JavaScript lernt, baute mit KI eine „Zähler"-App: Knopf drücken, Zahl um 1 erhöhen. Der KI-generierte Code funktionierte.

Dann wollte er auf „+2 pro Klick" umstellen und sagte der KI: „Lass jeden Klick um 2 erhöhen." Die KI änderte den Code, aber die Zahl stieg immer noch nur um 1.

Er fragte die KI, warum es nicht wirkte, und die KI erklärte einiges – aber er verstand nicht, was count = count + 1 bedeutete, und wusste nicht, ob die KI überhaupt an der richtigen Stelle geändert hatte. Er wiederholte nur „+2 funktioniert nicht", und die KI produzierte mehrere Versionen – mal wurde der Startwert auf 2 gesetzt, mal wurde an völlig falscher Stelle eine 2 eingefügt.

Schließlich las er Kapitel 2 über „Variablen" und verstand, dass count = count + 1 den Wert von count um 1 erhöht und wieder speichert. Dann sagte er der KI: „Ändere count + 1 in count + 2."

Ein Versuch – sofort richtig.

Deshalb musst du JavaScript verstehen – nicht um selbst Code zu schreiben, sondern um sofort zu erkennen, wo das Problem liegt, wenn die KI daneben liegt, und es mit einem Treffer zu benennen.

1.3 Ein erster Blick: echter KI-Code

Bevor wir tiefer einsteigen, schauen wir uns echten KI-generierten Code an. Keine Sorge, wenn du nicht alles verstehst – wir gehen jeden Teil später einzeln durch.

Szenario: Ein Button, der beim Klicken die Hintergrundfarbe wechselt

javascript
// Eine Reihe von Farben definieren
const colors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4']
let currentIndex = 0

// Den Button auf der Seite finden
const button = document.querySelector('#changeBtn')

// Dem Button ein Klick-Event hinzufügen
button.addEventListener('click', () => {
  currentIndex = (currentIndex + 1) % colors.length
  document.body.style.backgroundColor = colors[currentIndex]
})

Was macht dieser Code?

CodeFunktionKapitel
const colors = [...]Definiert eine Liste von FarbenKapitel 2: Arrays
let currentIndex = 0Merkt sich, welche Farbe gerade angezeigt wirdKapitel 2: Variablen
document.querySelector(...)Findet den Button auf der SeiteKapitel 4: DOM-Suche
button.addEventListener(...)Fügt dem Button ein Klick-Event hinzuKapitel 4: Event-Listener
() => {...}Definiert den Code, der beim Klick ausgeführt wirdKapitel 3: Arrow-Funktionen

💡 Kernbotschaft

Du musst nicht jede Zeile sofort verstehen. Merk dir nur: JavaScript-Code ist eine Reihe von Anweisungen, die dem Browser sagen: „Wenn der Nutzer X tut, soll Y passieren."


2. Daten: Variablen & Datentypen

🤔 Kernfrage

Wie „merkt" sich ein Programm Dinge? Nutzereingaben, Daten vom Server, Zwischenergebnisse – wo werden all diese Informationen gespeichert?

2.1 Variablen: Daten einen Namen geben

Eine Variable ist wie eine beschriftete Box – du legst Daten hinein und holst sie später über das Label wieder heraus.

javascript
const name = "Max"    // Name ändert sich nicht → const
let age = 25           // Alter kann sich ändern → let

Warum zwischen const und let unterscheiden?

Stell dir vor: Deine Personalausweisnummer (const) ändert sich nie, aber dein Alter (let) ändert sich jedes Jahr. JavaScript lässt dich diese Absicht mit unterschiedlichen Schlüsselwörtern ausdrücken.

SchlüsselwortVeränderbarEinsatzBeispiel
const❌ NeinDaten, die sich nicht ändernPersonalausweisnummer, Konfiguration, Farblisten
let✅ JaDaten, die sich ändernZähler, ausgewählte Option, Nutzereingabe
🔍 Ein konkretes Beispiel
javascript
// Mit const: Diese Werte ändern sich nicht
const PI = 3.14159
const MAX_USERS = 100
const APP_NAME = "TodoList"

// Mit let: Diese Werte ändern sich
let count = 0
count = 1  // ✅ kann geändert werden

count = count + 1  // ✅ Berechnung auf Basis des alten Werts

// Was passiert mit const?
const fixedCount = 0
fixedCount = 1  // ❌ Fehler! const kann nicht neu zugewiesen werden

👇 Probier's aus: Ändere den Code unten und sieh den Unterschied zwischen const und let

📦 Variables Are Named Boxes
const
name
Alice
🔒
let
age
25
🔓
const
isStudent
true
🔒
const name = "Alice"let age = 25

2.2 Datentypen: Die verschiedenen „Dinge" in JavaScript

JavaScript unterteilt Daten in Typen. Die drei häufigsten:

TypBedeutungBeispielPraxis
string (Zeichenkette)Text"hello", 'Hallo'Benutzername, Produktbeschreibung, Hinweistexte
number (Zahl)Numerischer Wert42, 3.14Preis, Anzahl, Bewertung
boolean (Wahrheitswert)Ja/Neintrue, falseEingeloggt?, Erledigt?, Sichtbar?

Zwei besondere Werte solltest du kennen:

  • undefined → Variable wurde deklariert, hat aber noch keinen Wert
  • null → Absichtlich auf „leer" gesetzt (bedeutet: „hier ist kein Wert")
🔍 Template-Strings: Text komfortabler zusammenbauen

In KI-Code siehst du oft Strings in Backticks (`) mit ${...}-Einschüben:

javascript
const name = "Max"
const age = 25

// Traditionell (umständlich)
const message = "Ich heiße " + name + " und bin " + age + " Jahre alt"

// Template-String (elegant)
const message = `Ich heiße ${name} und bin ${age} Jahre alt`
// Ergebnis: "Ich heiße Max und bin 25 Jahre alt"

Erkennungsmerkmal: Backticks und ${} bedeuten: Eine Variable wird in Text eingefügt.

2.3 Objekte & Arrays: Daten strukturieren

Objekt = eine Sammlung benannter Eigenschaften (wie ein Steckbrief)

javascript
const user = {
  name: "Max",
  age: 25,
  isVIP: true
}

// Zugriff über Punktnotation
console.log(user.name)    // "Max"
console.log(user.age)     // 25

Array = eine geordnete Liste von Daten (wie eine Aufzählung)

javascript
const colors = ['Rot', 'Grün', 'Blau']

// Zugriff über Index (beginnt bei 0)
console.log(colors[0])  // "Rot"
console.log(colors[1])  // "Grün"

Verschachtelte Strukturen: Objekte in Arrays, Arrays in Objekten

Das ist die häufigste Datenstruktur in KI-Code:

javascript
const todos = [
  { id: 1, text: "JavaScript lernen", done: false },
  { id: 2, text: "Projekt umsetzen", done: true },
  { id: 3, text: "Dokumentation schreiben", done: false }
]

// Zugriff: erstes Element des Arrays, dann dessen text-Eigenschaft
console.log(todos[0].text)  // "JavaScript lernen"

💡 Erkennungstipps

  • {} → ein Objekt mit Name: Wert-Paaren
  • [] → ein Array mit geordneten Werten
  • data[0].name → erstes Element des Arrays, dann dessen name-Eigenschaft

2.4 Wert vs. Referenz: Eine häufige Stolperfalle

Das ist eines der häufigsten Probleme für Anfänger!

Primitive Typen (string, number, boolean) zuweisen = eine unabhängige Kopie erstellen:

javascript
let a = 10
let b = a      // b bekommt eine Kopie von a
b = 20
console.log(a) // 10 (a bleibt unverändert)

Objekte und Arrays zuweisen = die „Adresse" kopieren (zeigen auf dasselbe Ding):

javascript
let user1 = { name: "Max" }
let user2 = user1      // user2 zeigt auf dasselbe Objekt
user2.name = "Moritz"  // user2 ändern wirkt sich auf user1 aus
console.log(user1.name) // "Moritz" (user1 hat sich auch geändert!)

Warum Kopien erstellen?

In React/Vue führt direktes Mutieren von Daten dazu, dass die Oberfläche nicht aktualisiert wird. Deshalb sieht man in KI-Code oft [...array] oder {...obj} – es wird eine Kopie erstellt, um Seiteneffekte zu vermeiden.

javascript
// Kopie mit Spread-Operator erstellen
const arr1 = [1, 2, 3]
const arr2 = [...arr1]     // Neues Array
arr2.push(4)
console.log(arr1)          // [1, 2, 3] (unverändert)
console.log(arr2)          // [1, 2, 3, 4]

👇 Probier's aus: Beobachte, wie sich das Original verhält, wenn du die Kopie veränderst

2.5 Destructuring & Spread: Kurzschreibweisen des modernen JavaScript

Diese beiden Syntaxformen tauchen überall in KI-Code auf – ohne sie zu kennen, liest du den Code vergebens.

Destructuring: Daten schnell aus Objekten oder Arrays extrahieren

javascript
const user = { name: "Max", age: 25, city: "Berlin" }

// Traditionell (umständlich)
const name = user.name
const age = user.age

// Destructuring (elegant)
const { name, age } = user
// Gleiches Ergebnis, eine Zeile

Spread-Operator: Daten kopieren und erweitern

javascript
// Array kopieren und neue Elemente hinzufügen
const arr1 = [1, 2, 3]
const arr2 = [...arr1, 4, 5]  // [1, 2, 3, 4, 5]

// Objekt kopieren und neue Eigenschaften hinzufügen
const user1 = { name: "Max", age: 25 }
const user2 = { ...user1, city: "Berlin" }
// { name: "Max", age: 25, city: "Berlin" }

💡 Erkennungstipps

  • const { name, age } = person → name und age aus dem person-Objekt extrahieren
  • ...array oder ...obj → Array oder Objekt „ausbreiten"
  • Du musst es nicht selbst schreiben können, aber lesen können musst du es

3. Logik: Funktionen & Ablaufsteuerung

🤔 Kernfrage

Wie „trifft" Code Entscheidungen und wie „wiederholt" er Dinge? Programme müssen je nach Bedingung unterschiedlich handeln und bestimmte Aufgaben wiederholen – wie drückt man diese Logik aus?

3.1 Bedingungen: Wenn … dann … sonst …

if/else: Die grundlegendste Bedingung

javascript
const age = 18

if (age >= 18) {
  console.log("Volljährig")
} else {
  console.log("Minderjährig")
}

Ternärer Operator: Kurzform von if/else

javascript
// Ausführlich (4 Zeilen)
let message
if (age >= 18) {
  message = "Volljährig"
} else {
  message = "Minderjährig"
}

// Ternärer Operator (1 Zeile)
const message = age >= 18 ? "Volljährig" : "Minderjährig"
// Format: Bedingung ? Wert wenn wahr : Wert wenn falsch

&&-Shortcut: Häufig in React-Code

javascript
// Nur wenn isLoggedIn true ist, wird das UserPanel angezeigt
isLoggedIn && <UserPanel />

// Entspricht:
if (isLoggedIn) {
  return <UserPanel />
}

💡 Erkennungstipps

  • ? : → Ternärer Operator, Kurzform von if/else
  • && → Nur wenn das linke true ist, wird das rechte ausgeführt

3.2 Funktionen: Aktionen verpacken

Funktion = Das Rezept eines Gerichts

  • Funktion definieren = Rezept aufschreiben
  • Funktion aufrufen = Nach Rezept kochen
  • Parameter = Zutaten
  • Rückgabewert = Das fertige Gericht
javascript
// Funktion definieren (Rezept aufschreiben)
function greet(name) {
  return "Hallo " + name
}

// Funktion aufrufen (nach Rezept kochen)
console.log(greet("Max"))    // "Hallo Max"
console.log(greet("Moritz")) // "Hallo Moritz"

Drei Schreibweisen auf einen Blick:

javascript
// 1. function-Deklaration (traditionell)
function greet(name) {
  return "Hallo " + name
}

// 2. Arrow-Funktion (am häufigsten in KI-Code)
const greet = (name) => {
  return "Hallo " + name
}

// 3. Arrow-Funktion Kurzform (nur eine Zeile)
const greet = (name) => "Hallo " + name

👇 Probier's aus: Gib verschiedene Namen ein und sieh, wie die Funktion arbeitet

💡 Erkennungstipps

  • function oder => → das ist eine Funktion
  • fn() → die Funktion wird aufgerufen
  • () => {} → Arrow-Funktion, der moderne JS-Standard

3.3 Array-Methoden: Werkzeuge für Listen

In React/Vue werden diese Methoden bei fast jeder Listen-Darstellung verwendet.

javascript
const todos = [
  { id: 1, text: "Lernen", done: false },
  { id: 2, text: "Arbeiten", done: true }
]

// .map(): Jedes Element in etwas anderes verwandeln
const texts = todos.map(todo => todo.text)
// ["Lernen", "Arbeiten"]

// .filter(): Elemente herausfiltern, die eine Bedingung erfüllen
const unfinished = todos.filter(todo => !todo.done)
// [{ id: 1, text: "Lernen", done: false }]

// .find(): Das erste Element finden, das eine Bedingung erfüllt
const found = todos.find(todo => todo.id === 1)
// { id: 1, text: "Lernen", done: false }

💡 Erkennungstipps

  • .map() → Array transformieren, gibt neues Array zurück
  • .filter() → Array filtern
  • items.map(item => <li>{item.name}</li>) → Jedes Datenelement in ein Listen-Tag verwandeln

3.4 Scope: Der „Sichtbarkeitsbereich" von Variablen

Die „Zimmer"-Analogie:

  • Variablen innerhalb einer Funktion sind wie Gegenstände im Zimmer – von außen unsichtbar
  • Aber vom Zimmer aus sieht man die Gegenstände im Flur (äußerer Scope)
javascript
const global = "Globale Variable"  // Gegenstand im Flur

function room() {
  const local = "Gegenstand im Zimmer"  // Gegenstand im Zimmer
  console.log(global)  // ✅ Kann den Flur sehen
}

console.log(local)  // ❌ Fehler! Von außen nicht ins Zimmer schauen

Kernintuition: Wo der Code steht, bestimmt, welche Variablen er sehen kann.

👇 Probier's aus: Klick auf verschiedene Scopes und sieh, welche Variablen zugänglich sind

🔍 Scope: where variables are visible

Global scope
appName= "Todo"
Function scope: greet()
appName= "Todo"← global
message= "Hello"
Block scope: if
appName= "Todo"← global
message= "Hello"← function
greeting= message+appName
💡 Variables visible here
In global scope, only the global variable appName is available.

Matching code

const appName = "Todo"  // global scope

function greet() {
  const message = "Hello"  // function scope

  if (true) {
    const greeting = message + appName  // block scope
    console.log(greeting)
  }

  console.log(greeting)  // ❌ Error. Outer code cannot see inner variables.
}

3.5 Closures: Eine Funktion „erinnert" sich an ihre Entstehungsumgebung

Betrachte es nicht als abstraktes Konzept, sondern verstehe es an einem konkreten Beispiel:

javascript
function setupCounter() {
  let count = 0  // Diese Variable befindet sich innerhalb der Funktion

  return {
    add: () => { count++; return count },
    getCount: () => count
  }
}

const counter = setupCounter()
console.log(counter.add())      // 1
console.log(counter.add())      // 2
console.log(counter.getCount()) // 2

Kernintuition: Eine Funktion „merkt" sich zum Zeitpunkt ihrer Erstellung die umgebenden Variablen, selbst wenn die äußere Funktion bereits beendet ist.

👇 Probier's aus: Beobachte, wie Closures einer Funktion erlauben, sich Zustände zu „merken"

3.6 this: Von wem wird die Funktion aufgerufen?

Keine komplizierten Bindungsregeln – nur die häufigsten Szenarien:

Szenario 1: In einer Objekt-Methode zeigt this auf das Objekt

javascript
const user = {
  name: "Max",
  sayHi() {
    console.log("Hallo, ich bin " + this.name)  // this zeigt auf user
  }
}
user.sayHi()  // "Hallo, ich bin Max"

Szenario 2: In einem Event-Listener zeigt this auf das auslösende Element

javascript
button.addEventListener('click', function() {
  console.log(this)  // this zeigt auf das button-Element
})

// Aber Arrow-Funktionen ändern this nicht
button.addEventListener('click', () => {
  console.log(this)  // this zeigt auf das äußere this
})

💡 Was tun bei Problemen?

Wenn im KI-Code ein this-bezogener Bug auftaucht (z. B. Cannot read property of undefined), sag der KI: „this in dieser Methode zeigt auf das falsche Objekt, ändere es in eine Arrow-Funktion oder nutze bind"


4. Interaktion: DOM, Events & Asynchronität

🤔 Kernfrage

Wie interagiert JavaScript mit der Webseite? Wie findet man Elemente auf der Seite? Wie reagiert man auf Klicks und Eingaben? Wie holt man Daten vom Server?

4.1 DOM: So sieht JavaScript die Webseite

Für JavaScript ist die Webseite ein „Baum", jedes HTML-Tag ein „Knoten" in diesem Baum.

html
<html>
  <body>
    <h1>Überschrift</h1>
    <p>Absatz</p>
    <ul>
      <li>Punkt 1</li>
      <li>Punkt 2</li>
    </ul>
  </body>
</html>

JS steuert die Webseite = Knoten finden + Knoten ändern + Knoten erstellen/löschen

👇 Probier's aus: Klick auf Knoten und sieh, wie der DOM-Baum aufgebaut ist

DOM Tree: the Webpage JavaScript Sees

My page

Welcome

  • Item 1
  • Item 2
<html>
<body>
<h1>My page
<p>Welcome
<ul>
<li>Item 1
<li>Item 2

Matching code

Click a button above to see the matching code

4.2 Elemente finden und verändern

Elemente finden:

javascript
// Über CSS-Selektor finden (am häufigsten)
const title = document.querySelector('h1')      // Erstes h1-Element
const button = document.querySelector('#btn')   // Element mit id="btn"
const items = document.querySelectorAll('.item') // Alle Elemente mit class="item"

Elemente verändern:

javascript
// Text ändern
title.textContent = "Neue Überschrift"

// Stil ändern
element.style.color = "red"
element.style.fontSize = "20px"

// CSS-Klasse ändern
element.classList.add('active')      // Klasse hinzufügen
element.classList.remove('hidden')   // Klasse entfernen
element.classList.toggle('open')     // Klasse umschalten (hinzufügen/entfernen)

💡 Erkennungstipps

  • document.querySelector → sucht ein Webseitenelement
  • .textContent → ändert Text
  • .style.xxx → ändert Stil
  • .classList.add/remove/toggle → ändert CSS-Klassen

4.3 Events: Wenn der Nutzer etwas tut …

addEventListener: Einem Element einen Event-Listener hinzufügen

javascript
button.addEventListener('click', () => {
  console.log("Button wurde geklickt")
})

Häufige Events:

EventAuslöserPraxis
clickKlickButton-Klick, Link-Navigation
inputEingabefeld ändert sichEchtzeitsuche, Formularvalidierung
submitFormular wird abgeschicktLogin, Registrierung, Daten senden
scrollSeite wird gescrolltLazy Loading, Zurück-nach-oben

Event-Objekt: Weitere Informationen abrufen

javascript
input.addEventListener('input', (e) => {
  console.log(e.target.value)  // Wert des Eingabefelds
  e.preventDefault()            // Standardverhalten unterbinden (z. B. Seite neu laden nach Submit)
})

💡 Praktische Anwendung

Wenn du einem Button eine Funktion hinzufügen willst, sagst du der KI im Grunde: „Füge diesem Button ein Klick-Event hinzu, das beim Klick folgende Aktion ausführt"

4.4 Asynchronität: Warum manche Operationen nicht sofort abgeschlossen sind

Restaurant-Analogie:

Nach der Bestellung stehst du nicht vor der Küchentür und wartest – du kannst andere Dinge tun, und wenn das Essen fertig ist, bringt es der Kellner.

Das häufigste Szenario: Daten vom Server abrufen

javascript
// Synchron (blockiert die Seite, nicht verwenden)
const data = fetch('/api/data')  // ❌ Das blockiert die Seite

// Asynchron (richtig)
async function loadData() {
  try {
    const response = await fetch('/api/data')
    const data = await response.json()
    console.log(data)
  } catch (error) {
    console.error('Fehler:', error)
  }
}

async/await-Syntax:

  • async → markiert die Funktion als „enthält asynchrone Operationen"
  • await → wartet auf Abschluss der Operation (blockiert die Seite aber nicht)
  • try/catch → behandelt mögliche Fehler

👇 Probier's aus: Beobachte die Ausführungsreihenfolge asynchroner Operationen

💡 Erkennungstipps

  • async/await → wartet auf eine zeitaufwändige Operation
  • fetch() → ruft Daten vom Server ab
  • try/catch → behandelt mögliche Fehler

4.5 Event Loop: Wie JavaScript wirklich funktioniert

Keine Fachbegriffe wie „Microtask/Macrotask" – ein einfaches Modell genügt:

JS ist ein „Einzelarbeitsplatz" – es macht immer nur eine Sache gleichzeitig, hat aber eine „To-do-Notizzettel"-Leiste (Task Queue).

Wenn eine wartende Operation ansteht (Netzwerkanfrage, Timer), wartet JS nicht untätig, sondern klebt „was tun, wenn fertig" auf den Notizzettel und macht mit dem restlichen Code weiter. Erst wenn die aktuelle Arbeit erledigt ist, schaut es auf den Zettel.

javascript
console.log("1")

setTimeout(() => console.log("2"), 0)  // Selbst 0 ms bedeuten Verzögerung

console.log("3")

// Ausgabe: 1, 3, 2 (nicht 1, 2, 3!)

Warum?

  1. console.log("1") ausführen → gibt 1 aus
  2. setTimeout antreffen → Callback auf den Notizzettel kleben, weitermachen
  3. console.log("3") ausführen → gibt 3 aus
  4. Aktueller Code ist fertig, auf den Notizzettel schauen
  5. setTimeout-Callback ausführen → gibt 2 aus

👇 Probier's aus: Beobachte die Ausführungsreihenfolge des Codes

Event Loop: How JavaScript Executes Code

Code queue

1
console.log("1")
Executing
2
setTimeout(() => console.log("2"), 0)
3
console.log("3")
4
fetch("/api").then(() => console.log("4"))
5
console.log("5")

Worker (single thread)

👨‍💻
Running
Run console.log("1")

Task queue

No pending tasks

Output log

Waiting for output...

Execution order: not started

Written order: 1, 2, 3, 4, 5

Code is written top to bottom, but it does not always run top to bottom because async work is delayed until the current code finishes.

💡 Was tun bei Problemen?

Wenn KI-Code die Seite rendert, bevor die Daten geladen sind, sag der KI: „Die Daten sind noch nicht geladen, aber das Rendering läuft schon. Füge einen Loading-State hinzu und rendere erst, wenn die Daten da sind."

4.6 Module: import und export

Die erste Zeile von KI-generiertem React/Vue-Code ist fast immer import.

import = Funktionalität aus einer anderen Datei einbinden

javascript
// Funktion aus einer Utility-Datei importieren
import { formatDate } from './utils'

// Aus einem Drittanbieter-Paket importieren
import React from 'react'
import { useState } from 'react'

export = Funktionalität für andere zur Nutzung bereitstellen

javascript
// utils.js
export function formatDate(date) {
  // ...
}

// Oder als Default-Export
export default function formatDate(date) {
  // ...
}

npm-Paket = Von anderen geschriebene Werkzeuge, nach Installation nutzbar

javascript
// Paket installieren: npm install lodash
// Paket verwenden
import _ from 'lodash'

💡 Erkennungstipps

  • import → Funktionalität aus anderer Datei einbinden
  • export → Funktionalität für andere bereitstellen
  • from 'react' → Aus dem React-Paket importieren
  • from './utils' → Aus lokaler Datei importieren

5. Praxis: Code lesen, Fehler verstehen, präzise beschreiben

🤔 Kernfrage

Du hast viel Syntax gelernt – wie wendest du das bei echtem KI-Code an? Wie liest du Code schnell? Was tust du bei Fehlermeldungen? Wie bringst du die KI dazu, deinen Code präzise zu ändern?

5.1 Wie du KI-Code liest

Vier-Schritte-Methode:

SchrittWorauf achten?Beispiel
1: GesamtstrukturWelche Funktionen gibt es? Was tun sie?loadData() lädt Daten, renderList() rendert die Liste
2: EinstiegspunktWo beginnt die Ausführung?addEventListener('click', ...) startet beim Klick
3: DatenflussWoher kommen die Daten? Wohin gehen sie?Von API abrufen → verarbeiten → auf Seite rendern
4: Detail-LogikWas passiert in den einzelnen Funktionen?Schleifen, Bedingungen, Berechnungen

Eine vollständige „Lese-Demo" mit dem Code aus Kapitel 1:

javascript
// Schritt 1: Gesamtstruktur
// - Ein Farb-Array
// - Eine Variable für den aktuellen Index
// - Ein Klick-Event auf einem Button

// Schritt 2: Einstiegspunkt
// button.addEventListener('click', ...) → wird beim Klick ausgeführt

// Schritt 3: Datenfluss
// colors (Farb-Array) → currentIndex (aktueller Index) → backgroundColor (Hintergrundfarbe)

// Schritt 4: Detail-Logik
// currentIndex = (currentIndex + 1) % colors.length
// Diese Formel bedeutet: jedes Mal +1, aber nie über die Array-Länge hinaus (zyklisch)

5.2 Häufige Fehlermeldungen – Kurzreferenz

FehlermeldungEinfach erklärtSo sagst du's der KI
TypeError: Cannot read properties of undefinedDu willst von etwas auf eine Eigenschaft zugreifen, das nicht existiert„Zeile X wirft einen Fehler, die Variable ist undefined, prüfe die Zuweisung"
ReferenceError: xxx is not definedEine nicht deklarierte Variable wurde verwendet„Variable xxx ist nicht definiert, möglicherweise Tippfehler oder fehlender Import"
TypeError: xxx is not a functionEtwas, das keine Funktion ist, wird als Funktion aufgerufen„xxx ist keine Funktion, prüfe Typ und Herkunft"
SyntaxError: Unexpected tokenSyntaxfehler (Klammer nicht geschlossen, Komma vergessen etc.)„Syntaxfehler in Zeile X, prüfe Klammern und Satzzeichen"
CORS errorBrowser blockiert Cross-Origin-Request„CORS-Fehler, Cross-Origin Resource Sharing muss konfiguriert werden"
404 Not FoundAngeforderte Ressource existiert nicht„API liefert 404, prüfe die Endpunkt-URL"

5.3 Wie du Probleme präzise beschreibst

Der Unterschied zwischen Anfängern und erfahrenen Entwicklern zeigt sich oft in der Präzision der Problembeschreibung.

❌ Schlechte Beschreibung✅ Gute Beschreibung
„Der Code hat einen Bug"„Beim Klick auf Löschen wird nicht das aktuelle, sondern das letzte Element gelöscht"
„Das Styling ist falsch"„Die Überschrift soll zentriert sein, ist aber linksbündig"
„Die Daten werden nicht angezeigt"„Die fetch-Anfrage liefert Daten (in der Console sichtbar), aber die Seite rendert nicht neu"
„Füge eine Funktion hinzu"„Füge auf der Benutzerliste ein Suchfeld hinzu, das die Liste beim Tippen in Echtzeit nach dem name-Feld filtert (unscharfe Suche)"
„Klick reagiert nicht"„Beim Klick auf den Button erscheint in der Console 'Cannot read property of undefined', Fehler in Zeile X"

Eine Praxisübung:

javascript
// Code mit Bug
function deleteTodo(index) {
  todos.splice(index, 1)  // Löscht immer das letzte Element
}

// Fehlerverhalten: Egal welcher Löschen-Button geklickt wird, es verschwindet immer das letzte Element

❌ Schlechte Beschreibung: „Die Löschfunktion hat einen Bug"

✅ Gute Beschreibung: „Beim Klick auf Löschen wird nicht das aktuelle, sondern das letzte Element gelöscht. Der Code nutzt splice(index, 1), aber der index ist wahrscheinlich falsch. Stattdessen sollte über die eindeutige id des Eintrags gelöscht werden."

5.4 Was du jetzt erkennen kannst

  • const/let → weißt, ob eine Variable neu zugewiesen werden kann
  • {} → Objekt / [] → Array
  • {...obj} oder [...arr] → Kopie wird erstellt
  • function oder => → ein wiederverwendbarer Codeblock ist definiert
  • if/else oder ? : → Code trifft eine Entscheidung
  • .map() / .filter() → Array wird transformiert oder gefiltert
  • document.querySelector → ein Webseitenelement wird gesucht
  • addEventListener → eine Nutzeraktion wird überwacht
  • async/await → eine zeitaufwändige Operation wird erwartet
  • import/export → Module werden ein- oder ausgeführt
  • Fehlermeldung → du verstehst den Kern und kannst ihn der KI präzise beschreiben

Wenn du die „Deep Dive"-Abschnitte in jedem Kapitel aufmerksam gelesen hast, beherrschst du auch diese Kernkonzepte:

  • Wert vs. Referenz: Primitive Typen kopieren Werte, Objekte/Arrays kopieren Adressen
  • Scope & Closures: Funktionen „merken" sich die Variablen ihrer Entstehungsumgebung
  • Das Wesen von this: Hängt davon ab, wer die Funktion aufruft, nicht wo sie steht
  • Event Loop: JS ist single-threaded, nutzt eine Task Queue für „Non-Blocking"-Verhalten

Diese Konzepte helfen dir, Probleme schneller einzugrenzen.

💡 Bei Problemen sag der KI:

  • „In Zeile X erscheint Fehler XXX, schau mal, was das Problem ist"
  • „Die Logik dieser Funktion macht XXX, aber das Ergebnis ist falsch, es sollte XXX sein"
  • „Ich möchte die XXX-Funktion ändern, die genauen Anforderungen sind: XXX"