Appearance
Kapitel 18: ES6 Interviewfragen
18.1 let / const / var Unterschied
📊 Frage 1: Was ist der Unterschied zwischen let, const und var?
Antwort-Struktur:
| Eigenschaft | var | let | const |
|---|---|---|---|
| Block-Scope | ❌ Nein | ✅ Ja | ✅ Ja |
| Hoisting | ✅ Ja (mit undefined) | ✅ Ja (in TDZ) | ✅ Ja (in TDZ) |
| Doppelte Deklaration | ✅ Erlaubt | ❌ Verboten | ❌ Verboten |
| Neu-Zuweisung | ✅ Erlaubt | ✅ Erlaubt | ❌ Verboten |
| Muss initialisiert werden | ❌ Nein | ❌ Nein | ✅ Ja |
| Empfehlung | ❌ Vermeiden | ✅ Für veränderliche Werte | ✅ Standard (Standard) |
📝 Musterantwort
Kurzfassung:
varhat keinen Block-Scope, nur Funktions-Scope. Es wird hochgezogen (hoisting) mitundefined.lethat Block-Scope, wird hochgezogen, befindet sich aber in der Temporal Dead Zone (TDZ) bis zur Deklaration.constist wielet, aber die Neu-Zuweisung ist verboten. Muss bei Deklaration initialisiert werden.
Code-Beispiel:
javascript
// var - Probleme
if (true) {
var x = 10;
}
console.log(x); // 10 ❌ (kein Block-Scope)
// let - Beser
if (true) {
let y = 20;
}
console.log(y); // ReferenceError ✅ (Block-Scope)
// const - Standard
const PI = 3.14159;
PI = 3.14; // TypeError ✅ (Neu-Zuweisung verboten)🎯 Folgefragen
Frage: Was ist die Temporal Dead Zone (TDZ)? Antwort: Die TDZ ist der Bereich zwischen dem Beginn des Scopes und der Deklaration der Variablen mit let oder const. In dieser Zone führt der Zugriff auf die Variable zu einem ReferenceError.
javascript
console.log(a); // undefined (Hoisting mit Initialisierung)
var a = 10;
console.log(b); // ReferenceError (TDZ)
let b = 20;18.2 Arrow Functions vs Normale Funktionen
📊 Frage 2: Was ist der Unterschied zwischen Arrow Functions und normalen Funktionen?
Antwort-Struktur:
| Aspekt | Normale Funktion | Arrow Function |
|---|---|---|
this | Dynamisch (wer aufruft) | Lexikalisch (umgebender Scope) |
arguments | ✅ Verfügbar | ❌ Nicht verfügbar |
Konstruktor (new) | ✅ Ja | ❌ Nein |
prototype | ✅ Hat prototype | ❌ Kein prototype |
| Syntax | Länger | Kürzer (Kurzschreibweise) |
📝 Musterantwort
Kurzfassung:
thisVerhalten: Normale Funktionen haben ein dynamischesthis(wer sie aufruft). Arrow Functions erbenthisaus dem umgebenden Scope (lexikalisch).- Kein eigenes
arguments: Arrow Functions haben kein eigenesargumentsObjekt. - Kein Konstruktor: Arrow Functions können nicht mit
newaufgerufen werden. - Kürzere Syntax: Arrow Functions erlauben eine kompaktere Schreibweise.
Code-Beispiel:
javascript
// Normale Funktion - this Problem
const person = {
name: "Max",
hobbies: ["Sport", "Lesen"],
printHobbies() {
this.hobbies.forEach(function(hobby) {
console.log(`${this.name} mag ${hobby}`); // ❌ this.name ist undefined
});
}
};
// Arrow Function - this Problem gelöst
const person2 = {
name: "Max",
hobbies: ["Sport", "Lesen"],
printHobbies() {
this.hobbies.forEach(hobby => {
console.log(`${this.name} mag ${hobby}`); // ✅ this.name = "Max"
});
}
};🎯 Folgefragen
Frage: Wann solltest du keine Arrow Function verwenden? Antwort:
- Bei Objekt-Methoden (da
thisdas Objekt sein soll). - Bei Klassen-Konstruktoren (da
newverwendet wird). - Bei Event Handlern, wo
thisdas DOM-Element sein soll.
javascript
// ❌ Falsch - Arrow Function für Methode
const person = {
name: "Max",
greet: () => {
console.log(`Hallo, ich bin ${this.name}`); // ❌ this ist nicht das Objekt
}
};
// ✅ Richtig - Normale Funktion für Methode
const person2 = {
name: "Max",
greet() {
console.log(`Hallo, ich bin ${this.name}`); // ✅ this = person2
}
};18.3 Promise: Prinzip und Verwendung
📊 Frage 3: Was ist ein Promise und wie funktioniert es?
Antwort-Struktur:
Ein Promise ist ein Objekt, das einen asynchronen Vorgang repräsentiert. Es kann drei Zustände haben:
- Pending (Anstehend) - Vorgang läuft noch.
- Fulfilled (Erfüllt) - Vorgang erfolgreich abgeschlossen.
- Rejected (Abgelehnt) - Vorgang fehlgeschlagen.
📝 Musterantwort
Kurzfassung:
- Promises dienen dazu, Callback Hell zu vermeiden und asynchrone Code besser lesbar zu machen.
- Ein Promise wird mit
new Promise((resolve, reject) => { ... })erstellt. - Bei Erfolg wird
resolve(ergebnis)aufgerufen, bei Fehlerreject(fehler). - Verwendet wird es mit
.then()(bei Erfolg),.catch()(bei Fehler) und.finally()(immer ausgeführt).
Code-Beispiel:
javascript
// Promise erstellen
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve("Daten erfolgreich geladen! ✅");
} else {
reject("Fehler beim Laden! ❌");
}
}, 1000);
});
// Promise verwenden
myPromise
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => console.log("Bereinigung (immer ausgeführt)"));🎯 Folgefragen
Frage: Was ist der Unterschied zwischen Promise.all() und Promise.race()? Antwort:
Promise.all()führt mehrere Promises parallel aus und gibt die Ergebnisse in einem Array zurück. Wenn eines fehlschlägt, wird sofort dercatch()Block ausgeführt.Promise.race()gibt das Ergebnis des ersten Promises zurück, das abgeschlossen wird (egal ob Erfolg oder Fehler).
javascript
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = new Promise((resolve, reject) => setTimeout(() => resolve(3), 1000));
// Promise.all()
Promise.all([p1, p2, p3])
.then(results => console.log(results)); // [1, 2, 3] (nach 1 Sekunde)
// Promise.race()
Promise.race([p1, p3])
.then(result => console.log(result)); // 1 (sofort)18.4 Destructuring, Spread-Operator Verwendung
📊 Frage 4: Was ist Destructuring und wie wird es verwendet?
Antwort-Struktur:
Destructuring erlaubt es, Werte aus Arrays oder Objekten in einzelne Variablen zu extrahieren.
| Typ | Syntax | Beschreibung |
|---|---|---|
| Array-Destructuring | const [a, b] = array; | Extrahiert Werte nach Position |
| Object-Destructuring | const { name, alter } = obj; | Extrahiert Werte nach Namen |
| Standardwerte | const { name = "Gast" } = obj; | Verwendet Standardwert, wenn undefined |
| Umbenennen | const { name: vorname } = obj; | Benennt die Variable um |
| Rest-Operator | const [a, ...rest] = array; | Sammelt restliche Werte in einem Array/Objekt |
📝 Musterantwort
Kurzfassung:
- Array-Destructuring: Extrahiert Werte basierend auf der Position.
- Object-Destructuring: Extrahiert Werte basierend auf dem Schlüsselnamen.
- Vorteile: Kürzere Syntax, bessere Lesbarkeit, Standardwerte, Umbenennen.
Code-Beispiel:
javascript
// Array-Destructuring
const colors = ["rot", "grün", "blau"];
const [first, second] = colors;
console.log(first, second); // "rot", "grün"
// Object-Destructuring
const person = { name: "Max", alter: 25, stadt: "Berlin" };
const { name, alter } = person;
console.log(name, alter); // "Max", 25
// Standardwerte + Umbenennen
const { name: vorname, land = "Deutschland" } = { name: "Max" };
console.log(vorname, land); // "Max", "Deutschland"
// Rest-Operator
const [a, ...rest] = [1, 2, 3, 4, 5];
console.log(a, rest); // 1, [2, 3, 4, 5]📊 Frage 5: Was ist der Spread-Operator und wie wird er verwendet?
Antwort-Struktur:
Der Spread-Operator (...) entpackt ein iterierbares Element (Array, String, Objekt) in einzelne Elemente.
| Verwendung | Syntax | Beschreibung |
|---|---|---|
| Array kopieren | const copy = [...array]; | Echte Kopie (Shallow Copy) |
| Array zusammenführen | const combined = [...arr1, ...arr2]; | Verbindet Arrays |
| Objekt kopieren | const copy = { ...obj }; | Echte Kopie (ES2018+) |
| Objekt zusammenführen | const combined = { ...obj1, ...obj2 }; | Verbindet Objekte |
| String in Array | const chars = [...str]; | Jedes Zeichen wird ein Element |
📝 Musterantwort
Kurzfassung:
- Der Spread-Operator wird verwendet, um Arrays oder Objekte zu kopieren, zusammenzuführen oder in einzelne Elemente zu entpacken.
- Bei Objekten werden nur die eigenen aufzählbaren Eigenschaften kopiert (Shallow Copy).
Code-Beispiel:
javascript
// Array kopieren + zusammenführen
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const copy = [...arr1]; // Kopie
const combined = [...arr1, ...arr2]; // Zusammenführen
console.log(copy, combined); // [1, 2, 3], [1, 2, 3, 4, 5, 6]
// Objekt kopieren + zusammenführen
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const copyObj = { ...obj1 }; // Kopie
const combinedObj = { ...obj1, ...obj2 }; // Zusammenführen
console.log(copyObj, combinedObj); // { a:1, b:2 }, { a:1, b:2, c:3, d:4 }
// String in Array
const str = "Hallo";
const chars = [...str];
console.log(chars); // ["H", "a", "l", "l", "o"]🎯 Folgefragen
Frage: Was ist der Unterschied zwischen Rest-Parameter und Spread-Operator? Antwort:
- Rest-Parameter (
...args): Sammelt mehrere Argumente in einem Array (bei Funktionsparametern). - Spread-Operator (
...): Entpackt ein Array oder Objekt in einzelne Elemente.
javascript
// Rest-Parameter
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3)); // 6
// Spread-Operator
const numbers = [1, 2, 3];
console.log(...numbers); // 1 2 3
console.log(Math.max(...numbers)); // 318.5 Asynchrone Programmierung: Entwicklung (Callback → Promise → async/await)
📊 Frage 6: Beschreibe die Entwicklung der asynchronen Programmierung in JavaScript.
Antwort-Struktur:
| Stufe | Technologie | Beschreibung | Probleme |
|---|---|---|---|
| 1. Callbacks | Callback-Funktionen | Übergeben einer Funktion als Argument | Callback Hell (Verschachtelung) |
| 2. Promises | new Promise() | Objekt zur Repräsentation asynchroner Vorgänge | Etwas komplexe Syntax |
| 3. async/await | async / await | Syntax-Zucker über Promises | Keine (modernste Methode) |
📝 Musterantwort
Kurzfassung:
- Callbacks: Die älteste Methode. Eine Funktion wird als Argument übergeben und später aufgerufen. Problem: Callback Hell (tiefe Verschachtelung).
- Promises: introduces
new Promise(),.then(),.catch(). Vorteil: Bessere Lesbarkeit, Fehlerbehandlung zentralisiert. - async/await: Eingeführt in ES2017. Macht asynchronen Code wie synchronen Code lesbar. Verwendet
try...catchfür Fehlerbehandlung.
Code-Beispiel:
javascript
// 1. Callbacks (Callback Hell)
function getUserCallback() {
getUserId((userId) => {
getUserName(userId, (name) => {
console.log(name); // Tief verschachtelt 😱
});
});
}
// 2. Promises
function getUserPromise() {
getUserId()
.then(userId => getUserName(userId))
.then(name => console.log(name))
.catch(error => console.error(error));
}
// 3. async/await (modernste Methode)
async function getUserAsync() {
try {
const userId = await getUserId();
const name = await getUserName(userId);
console.log(name);
} catch (error) {
console.error(error);
}
}🎯 Folgefragen
Frage: Was macht await? Antwort: await pausiert die Ausführung einer async Funktion, bis das Promise aufgelöst wird. Es kann nur innerhalb von async Funktionen verwendet werden.
javascript
async function fetchData() {
console.log("Laden...");
const result = await somePromise; // Pausiert hier
console.log("Fertig!", result); // Macht weiter, wenn Promise aufgelöst
}🎉 Zusammenfassung
In diesem Kapitel hast du gelernt:
- ✅
let/const/varUnterschied (Scope, Hoisting, TDZ) - ✅ Arrow Functions vs Normale Funktionen (
thisVerhalten,arguments, Konstruktor) - ✅ Promise: Prinzip und Verwendung (Pending, Fulfilled, Rejected,
.then(),.catch(),.finally()) - ✅ Destructuring, Spread-Operator Verwendung (Array/Object Destructuring, Rest-Operator, Kopieren, Zusammenführen)
- ✅ Asynchrone Programmierung: Entwicklung (Callback → Promise → async/await)
📝 Übung
Interviewfrage simulieren:
javascript// Bereite eine Antwort auf die Frage vor: // "Was ist der Unterschied zwischen Promise.all() und Promise.race()?"Code-Beispiel erstellen:
javascript// Erstelle ein Beispiel, das Destructuring, Spread-Operator und Arrow Functions kombiniertasync/await vs Promise:
javascript// Schreibe dieselbe asynchrone Funktion einmal mit Promises und einmal mit async/await
➡️ Nächstes Kapitel
In Kapitel 19 lernen wir ES6+ neuere Versionen (ES7~ES13) - optionale Verkettung, Nullish Coalescing, logische Zuweisungsoperatoren, Zahlen-Trennzeichen und mehr!
