Files
it-know-how/Computerkram/JavaScript/JavaScript Tutorial.md
T
2026-03-27 12:41:00 +01:00

740 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
```markdown
---
title: JavaScript Tutorial (für Python-Erfahrene)
tags: [javascript, tutorial, beginner, programming]
created: 2026-03-27
---
# JavaScript Tutorial (für Python-Erfahrene)
Ziel: Du lernst JavaScript von Grund auf, aber mit Fokus auf das, was du als Python-Erfahrener schnell einordnen kannst. Viele Beispiele sind so gestaltet, dass du sie 1:1 nachbauen und variieren kannst.
---
## Inhaltsverzeichnis
1. [[#0 Wie führe ich JavaScript am besten aus]]
2. [[#1 Grundsyntax & Variablen]]
3. [[#2 Datentypen, Equality, Truthy/Falsy]]
4. [[#3 Strings & Template Literals]]
5. [[#4 Arrays (Listen) & Methoden]]
6. [[#5 Objekte (Dictionaries) & JSON]]
7. [[#6 Kontrollfluss (if, switch, Schleifen)]]
8. [[#7 Funktionen (inkl. Arrow Functions)]]
9. [[#8 Scope, Hoisting, Closures]]
10. [[#9 Module (import/export)]]
11. [[#10 Klassen & Prototypen]]
12. [[#11 Fehlerbehandlung (try/catch)]]
13. [[#12 Asynchronität: Event Loop, Promises, async/await]]
14. [[#13 DOM: Webseiten manipulieren]]
15. [[#14 Events (Click, Input, Delegation)]]
16. [[#15 Fetch API (HTTP), APIs, JSON]]
17. [[#16 Praktische Mini-Projekte]]
18. [[#17 Tooling: npm, Vite, Linting (kurz)]]
19. [[#18 Cheatsheet: Python vs. JavaScript]]
---
## 0) Wie führe ich JavaScript am besten aus?
### Option A — Browser-Konsole (schnell zum Experimentieren)
1. Öffne eine Website (z. B. `about:blank`)
2. DevTools öffnen:
- Chrome/Edge: `F12` oder `Ctrl+Shift+I`
- macOS: `Cmd+Opt+I`
3. Tab **Console** → JavaScript eintippen.
Beispiel:
```js
console.log("Hello JS!");
```
**Pro:** sofortiges Feedback
**Contra:** nicht so gut für größere Projekte
---
### Option B — HTML + `<script>` direkt im HTML (einfach)
Erstelle `index.html`:
```html
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<title>JS Tutorial</title>
</head>
<body>
<h1>Hallo JavaScript</h1>
<script>
console.log("JS läuft!");
</script>
</body>
</html>
```
Öffne die Datei im Browser (Doppelklick) und dann DevTools → Console.
---
### Option C — HTML + externes `.js` File (empfohlen)
Das ist die gängigste Lern- und Projektstruktur.
`index.html`:
```html
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<title>JS Tutorial</title>
<script defer src="./main.js"></script>
</head>
<body>
<h1>Hallo JavaScript</h1>
<button id="btn">Klick mich</button>
</body>
</html>
```
`main.js`:
```js
console.log("main.js geladen");
document.querySelector("#btn").addEventListener("click", () => {
console.log("Button geklickt");
});
```
**Wichtig:** `defer` sorgt dafür, dass das HTML zuerst geparst wird, bevor dein JS läuft (sehr praktisch für DOM-Skripte).
---
### Option D — Node.js (JavaScript außerhalb des Browsers)
Installiere Node.js (LTS). Dann im Terminal:
```bash
node -v
node
```
Oder Datei:
`app.js`:
```js
console.log("Hallo aus Node!");
```
Run:
```bash
node app.js
```
**Merke:** Browser-JS hat DOM/Web-APIs, Node hat dafür File-System etc.
---
## 1) Grundsyntax & Variablen
### `let`, `const`, (vermeide `var`)
```js
let x = 10; // kann neu zugewiesen werden
x = 11;
const y = 20; // darf nicht neu zugewiesen werden
// y = 21; // TypeError
const obj = { a: 1 };
obj.a = 2; // erlaubt! (Objektinhalt mutiert)
// obj = { a: 3 }; // nicht erlaubt (Neuzuweisung)
```
**Python-Vergleich:** `const` ist kein echtes Immutable wie `tuple`, sondern verhindert nur Reassignment der Variable.
---
## 2) Datentypen, Equality, Truthy/Falsy
### Primitive Typen
- `number` (integers + floats)
- `string`
- `boolean`
- `undefined`
- `null`
- `bigint`
- `symbol`
```js
let a; // undefined
let b = null; // absichtlich "leer"
```
### `==` vs `===` (wichtig)
- `===` vergleicht **ohne** Typumwandlung → nutze das fast immer
- `==` macht implizite Konvertierung → vermeide für Anfänger
```js
0 == false // true (komisch)
0 === false // false (gut/strikt)
"5" == 5 // true
"5" === 5 // false
```
### Truthy / Falsy
Falsy sind u. a.: `false`, `0`, `""`, `null`, `undefined`, `NaN`
```js
if ("") console.log("läuft nicht");
if ("0") console.log("läuft"); // nicht leerer String ist truthy
```
---
## 3) Strings & Template Literals
```js
const name = "Ada";
const age = 30;
console.log("Hallo " + name + ", du bist " + age);
console.log(`Hallo ${name}, du bist ${age}`); // Template Literal
```
Nützliche String-Methoden:
```js
"Hello".toUpperCase(); // "HELLO"
" hi ".trim(); // "hi"
"abc".includes("b"); // true
"1,2,3".split(","); // ["1","2","3"]
```
---
## 4) Arrays (Listen) & Methoden
```js
const nums = [1, 2, 3];
nums.push(4); // [1,2,3,4]
nums.pop(); // entfernt letztes
nums[0]; // 1
```
### Iteration
```js
for (const n of nums) {
console.log(n);
}
```
### `map`, `filter`, `reduce` (sehr wichtig)
```js
const doubled = nums.map(n => n * 2); // [2,4,6]
const evens = nums.filter(n => n % 2 === 0); // [2]
const sum = nums.reduce((acc, n) => acc + n, 0); // 6
```
**Python-Vergleich:** `map/filter/reduce` ähnlich, aber in JS extrem häufig in UI/Frontend.
---
## 5) Objekte (Dictionaries) & JSON
### Objekte (Key-Value)
```js
const user = {
name: "Ada",
age: 30,
isAdmin: true
};
console.log(user.name);
console.log(user["age"]);
```
### Dynamische Keys
```js
const key = "score";
const obj = { [key]: 42 };
console.log(obj.score); // 42
```
### Object Destructuring
```js
const { name, age } = user;
console.log(name, age);
```
### Spread (Kopieren/Mergen)
```js
const a = { x: 1, y: 2 };
const b = { ...a, y: 999, z: 3 }; // {x:1,y:999,z:3}
```
### JSON
```js
const json = JSON.stringify(user);
const parsed = JSON.parse(json);
```
---
## 6) Kontrollfluss (if, switch, Schleifen)
```js
const n = 7;
if (n > 10) {
console.log("groß");
} else if (n > 5) {
console.log("mittel");
} else {
console.log("klein");
}
```
### `switch`
```js
const role = "admin";
switch (role) {
case "admin":
console.log("Alles erlaubt");
break;
case "user":
console.log("Standardrechte");
break;
default:
console.log("Unbekannt");
}
```
### Schleifen
```js
for (let i = 0; i < 3; i++) console.log(i);
let i = 0;
while (i < 3) {
console.log(i);
i++;
}
```
---
## 7) Funktionen (inkl. Arrow Functions)
### Funktionsdeklaration
```js
function add(a, b) {
return a + b;
}
```
### Function Expression
```js
const add2 = function (a, b) {
return a + b;
};
```
### Arrow Function
```js
const add3 = (a, b) => a + b;
```
### Default-Parameter
```js
function greet(name = "Welt") {
return `Hallo ${name}`;
}
```
### Rest-Parameter
```js
function sum(...nums) {
return nums.reduce((acc, n) => acc + n, 0);
}
sum(1, 2, 3); // 6
```
---
## 8) Scope, Hoisting, Closures
### Block-Scope: `let/const`
```js
if (true) {
let x = 1;
}
// console.log(x); // ReferenceError
```
### Hoisting (vereinfachte Regel)
- `var` wird “hochgezogen” → vermeiden
- `let/const` existieren zwar “vorher”, sind aber in der **Temporal Dead Zone** → besser/strikter
### Closure
```js
function makeCounter() {
let count = 0;
return function () {
count++;
return count;
};
}
const c = makeCounter();
c(); // 1
c(); // 2
```
**Python-Vergleich:** ähnlich wie inner functions mit captured variables.
---
## 9) Module (import/export)
**Browser-Module**: In HTML:
```html
<script type="module" src="./main.js"></script>
```
`math.js`:
```js
export function add(a, b) {
return a + b;
}
export const PI = 3.14159;
```
`main.js`:
```js
import { add, PI } from "./math.js";
console.log(add(2, 3));
console.log(PI);
```
---
## 10) Klassen & Prototypen
### Klasse
```js
class User {
constructor(name) {
this.name = name;
}
greet() {
return `Hi ${this.name}`;
}
}
const u = new User("Ada");
console.log(u.greet());
```
### Vererbung
```js
class Admin extends User {
constructor(name) {
super(name);
this.role = "admin";
}
}
const a = new Admin("Grace");
```
**Merke:** JS ist prototyp-basiert; `class` ist syntactic sugar.
---
## 11) Fehlerbehandlung (try/catch)
```js
try {
JSON.parse("{ broken");
} catch (err) {
console.error("Parsing fehlgeschlagen:", err.message);
} finally {
console.log("läuft immer");
}
```
Eigene Fehler:
```js
function requirePositive(n) {
if (n <= 0) throw new Error("n muss > 0 sein");
return n;
}
```
---
## 12) Asynchronität: Event Loop, Promises, async/await
### Warum async?
Im Browser soll UI nicht blockieren. In Node gehts um I/O.
### Promise Basics
```js
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve("fertig"), 500);
});
p.then(value => console.log(value));
```
### `async/await` (empfohlen)
```js
function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function run() {
console.log("start");
await wait(300);
console.log("nach 300ms");
}
run();
```
### Parallel vs. sequenziell
```js
async function parallel() {
const p1 = wait(200);
const p2 = wait(300);
await Promise.all([p1, p2]);
console.log("beide fertig");
}
```
---
## 13) DOM: Webseiten manipulieren
### Elemente finden
```js
const h1 = document.querySelector("h1");
const items = document.querySelectorAll("li");
```
### Text/HTML ändern
```js
h1.textContent = "Neuer Titel";
h1.innerHTML = "<em>Kursiv</em>"; // vorsichtig (XSS bei fremden Daten!)
```
### Klassen und Styles
```js
h1.classList.add("highlight");
h1.style.color = "tomato";
```
### Elemente erstellen & anhängen
```js
const ul = document.querySelector("ul");
const li = document.createElement("li");
li.textContent = "Neues Item";
ul.appendChild(li);
```
---
## 14) Events (Click, Input, Delegation)
`index.html`:
```html
<input id="name" placeholder="Name" />
<button id="save">Speichern</button>
<div id="out"></div>
```
`main.js`:
```js
const input = document.querySelector("#name");
const btn = document.querySelector("#save");
const out = document.querySelector("#out");
btn.addEventListener("click", () => {
out.textContent = `Hallo ${input.value}`;
});
```
### Event Delegation (praktisch bei Listen)
```js
document.querySelector("#list").addEventListener("click", (e) => {
if (e.target.matches("li")) {
console.log("geklickt:", e.target.textContent);
}
});
```
---
## 15) Fetch API (HTTP), APIs, JSON
### GET Request
```js
async function loadTodo() {
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log(data);
}
loadTodo().catch(console.error);
```
### POST Request
```js
async function createPost() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "Hi", body: "Text", userId: 1 })
});
const data = await res.json();
console.log("created:", data);
}
```
---
## 16) Praktische Mini-Projekte
### Projekt 1: Counter
`index.html`:
```html
<h1 id="count">0</h1>
<button id="dec">-</button>
<button id="inc">+</button>
<button id="reset">reset</button>
<script defer src="./main.js"></script>
```
`main.js`:
```js
let count = 0;
const el = document.querySelector("#count");
const render = () => (el.textContent = String(count));
document.querySelector("#inc").addEventListener("click", () => {
count++;
render();
});
document.querySelector("#dec").addEventListener("click", () => {
count--;
render();
});
document.querySelector("#reset").addEventListener("click", () => {
count = 0;
render();
});
render();
```
### Projekt 2: Todo-Liste (minimal)
`index.html`:
```html
<input id="todo" placeholder="Neues Todo" />
<button id="add">Add</button>
<ul id="list"></ul>
<script defer src="./main.js"></script>
```
`main.js`:
```js
const input = document.querySelector("#todo");
const btn = document.querySelector("#add");
const list = document.querySelector("#list");
btn.addEventListener("click", () => {
const text = input.value.trim();
if (!text) return;
const li = document.createElement("li");
li.textContent = text;
list.appendChild(li);
input.value = "";
input.focus();
});
// Klick zum Entfernen (Delegation)
list.addEventListener("click", (e) => {
if (e.target.matches("li")) e.target.remove();
});
```
---
## 17) Tooling: npm, Vite, Linting (kurz)
Wenn du über “nur HTML+JS” hinaus willst (Module, Bundling, Dev-Server):
### Vite Setup
```bash
npm create vite@latest my-app
cd my-app
npm install
npm run dev
```
Das erstellt ein modernes Dev-Setup mit Hot Reload.
### Linting (optional)
- ESLint hilft, typische Fehler früh zu finden.
- Prettier formatiert Code automatisch.
---
## 18) Cheatsheet: Python vs. JavaScript
### Datenstrukturen
- Python `list` ≈ JS `Array`
- Python `dict` ≈ JS `Object` oder `Map`
- Python `None` ≈ JS `null` (oder `undefined` je nach Kontext)
### Funktionen
- Python: `def f(a=1): ...`
- JS: `function f(a = 1) { ... }` oder `(a = 1) => ...`
### Strings
- Python: `f"{x}"`
- JS: `` `${x}` ``
### Imports
- Python: `import x`
- JS (ESM): `import x from "./x.js"` / `import {a} from ...`
### Iteration
- Python: `for x in xs:`
- JS: `for (const x of xs) { ... }`
### Async
- Python: `async def`, `await`
- JS: `async function`, `await` (sehr ähnlich im Feeling, andere Runtime-Details)
---
## Nächste Schritte (Empfehlung)
1. Baue die Mini-Projekte nach und verändere sie (z. B. Todo: “erledigt” toggle statt löschen).
2. Übe `map/filter/reduce` auf Arrays mit echten Daten (z. B. aus `fetch`).
3. Wenn du Web-Apps willst: lerne danach ein Framework (React/Vue/Svelte) aber erst, wenn DOM + async sitzen.
---
## Offene Fragen (damit ich das Tutorial besser anpassen kann)
- Willst du primär **Frontend im Browser** lernen oder auch **Node.js Backend**?
- Arbeitest du lieber mit **Vanilla JS** (ohne Framework) oder willst du schnell Richtung **React/Vue**?
```
Wenn du willst, kann ich daraus auch mehrere Obsidian-Notizen machen (z. B. „JS Basics“, „DOM“, „Async“, „Mini-Projekte“) und dir eine sinnvolle Link-Struktur (MOC) anlegen.