JavaScript Destructuring Spread
Destructuring und Spread Operator
Destructuring und Spread machen JavaScript-Code kürzer und lesbarer. Lernen Sie das elegante Entpacken und Zusammenführen von Daten.
Array Destructuring
const colors = ['rot', 'grün', 'blau', 'gelb']; // Grundlagen const [first, second] = colors; console.log(first); // 'rot' console.log(second); // 'grün' // Elemente überspringen const [, , third] = colors; console.log(third); // 'blau' // Rest-Element (sammelt den Rest) const [primary, ...rest] = colors; console.log(primary); // 'rot' console.log(rest); // ['grün', 'blau', 'gelb'] // Standardwerte const [a, b, c, d, e = 'standard'] = colors; console.log(e); // 'standard' // Variablen tauschen let x = 1, y = 2; [x, y] = [y, x]; console.log(x, y); // 2, 1 // Verschachtelt const matrix = [[1, 2], [3, 4]]; const [[a1, a2], [b1, b2]] = matrix; console.log(a1, b2); // 1, 4
Objekt Destructuring
const user = {
name: 'Max',
age: 30,
email: 'max@example.com',
address: {
city: 'Berlin',
zip: '10115'
}
};
// Grundlagen
const { name, age } = user;
console.log(name); // 'Max'
console.log(age); // 30
// Umbenennung
const { name: userName, age: userAge } = user;
console.log(userName); // 'Max'
// Standardwerte
const { name, role = 'user' } = user;
console.log(role); // 'user'
// Umbenennung + Standardwert
const { name: n, role: r = 'guest' } = user;
// Verschachtelt
const { address: { city, zip } } = user;
console.log(city); // 'Berlin'
// Rest-Properties
const { name, ...others } = user;
console.log(others); // { age: 30, email: '...', address: {...} }
Destructuring in Funktionen
// Parameter destructuren
function greet({ name, age }) {
return `Hallo ${name}, du bist ${age} Jahre alt`;
}
greet({ name: 'Max', age: 30 }); // "Hallo Max, du bist 30 Jahre alt"
// Mit Standardwerten
function createUser({ name, role = 'user', active = true } = {}) {
return { name, role, active };
}
createUser({ name: 'Max' });
// { name: 'Max', role: 'user', active: true }
createUser(); // Funktioniert wegen = {}
// { name: undefined, role: 'user', active: true }
// Array destructuring in Parametern
function sum([a, b, c = 0]) {
return a + b + c;
}
sum([1, 2]); // 3
sum([1, 2, 3]); // 6
// In forEach/map
const users = [
{ name: 'Max', age: 30 },
{ name: 'Anna', age: 25 }
];
users.forEach(({ name, age }) => {
console.log(`${name}: ${age}`);
});
Spread Operator - Arrays
const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; // Arrays zusammenführen const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6] // Element hinzufügen const withNew = [...arr1, 4]; // [1, 2, 3, 4] // Am Anfang hinzufügen const prepended = [0, ...arr1]; // [0, 1, 2, 3] // In der Mitte einfügen const inserted = [...arr1.slice(0, 2), 'neu', ...arr1.slice(2)]; // [1, 2, 'neu', 3] // Array kopieren (shallow copy) const copy = [...arr1]; copy.push(4); console.log(arr1); // [1, 2, 3] - unverändert // String zu Array const chars = [..."Hello"]; // ['H', 'e', 'l', 'l', 'o'] // Set zu Array (Duplikate entfernen) const unique = [...new Set([1, 2, 2, 3, 3])]; // [1, 2, 3] // Als Funktionsargumente const numbers = [1, 2, 3]; console.log(Math.max(...numbers)); // 3
Spread Operator - Objekte
const defaults = {
theme: 'light',
language: 'de',
notifications: true
};
const userPrefs = {
theme: 'dark'
};
// Objekte zusammenführen (spätere überschreiben frühere)
const settings = { ...defaults, ...userPrefs };
// { theme: 'dark', language: 'de', notifications: true }
// Property hinzufügen
const extended = { ...settings, newProp: 'value' };
// Property überschreiben
const updated = { ...settings, theme: 'blue' };
// Shallow Copy
const copy = { ...settings };
// Verschachtelte Objekte NICHT deep-copied!
const user = {
name: 'Max',
address: { city: 'Berlin' }
};
const userCopy = { ...user };
userCopy.address.city = 'Hamburg';
console.log(user.address.city); // 'Hamburg' - auch geändert!
// Deep Copy (moderne Lösung)
const deepCopy = structuredClone(user);
Rest vs. Spread
// REST - sammelt Elemente (in Destructuring/Parametern)
// Steht am ENDE
// In Destructuring
const [first, ...rest] = [1, 2, 3, 4];
// first = 1, rest = [2, 3, 4]
const { name, ...others } = { name: 'Max', age: 30, city: 'Berlin' };
// name = 'Max', others = { age: 30, city: 'Berlin' }
// In Funktionsparametern
function log(first, ...rest) {
console.log(first); // Erstes Argument
console.log(rest); // Array der restlichen
}
log(1, 2, 3, 4); // first=1, rest=[2,3,4]
// SPREAD - verteilt Elemente (in Arrays/Objekten/Aufrufen)
// Kann überall stehen
const arr = [...[1, 2], 3, ...[4, 5]];
// [1, 2, 3, 4, 5]
func(...args); // Argumente verteilen
Praktische Beispiele
// 1. Funktion mit Options-Objekt
function createButton({
text = 'Button',
color = 'blue',
onClick = () => {},
disabled = false
} = {}) {
return { text, color, onClick, disabled };
}
createButton({ text: 'Senden', color: 'green' });
// 2. Immutable State Update (React-Pattern)
const state = {
user: { name: 'Max', age: 30 },
posts: [1, 2, 3],
loading: false
};
// User-Name ändern (immutable)
const newState = {
...state,
user: {
...state.user,
name: 'Anna'
}
};
// Array-Element hinzufügen (immutable)
const withNewPost = {
...state,
posts: [...state.posts, 4]
};
// 3. Mehrere Rückgabewerte
function getMinMax(numbers) {
return [Math.min(...numbers), Math.max(...numbers)];
}
const [min, max] = getMinMax([5, 2, 8, 1, 9]);
// min = 1, max = 9
// 4. Named Parameters simulieren
function createUser({ name, email, age }) {
// Reihenfolge egal beim Aufruf
return { name, email, age, createdAt: new Date() };
}
createUser({ age: 30, name: 'Max', email: 'max@mail.de' });
// 5. Objekt aus Variablen (Shorthand)
const name = 'Max';
const age = 30;
// Statt { name: name, age: age }
const user = { name, age };
Fallstricke
// ❌ Rest muss am Ende stehen
// const [first, ...middle, last] = arr; // SyntaxError!
// ❌ Spread in Objekten nur für iterables
// const obj = { ...'string' }; // Funktioniert (Indices als Keys)
// const obj = { ...123 }; // TypeError!
// ❌ Shallow Copy bei verschachtelten Strukturen
const original = { nested: { value: 1 } };
const copy = { ...original };
copy.nested.value = 2;
console.log(original.nested.value); // 2 - Auch geändert!
// ✅ Deep Copy mit structuredClone
const deepCopy = structuredClone(original);
// ❌ Spread erstellt keine Prototypen-Kette
class User {
greet() { return 'Hi'; }
}
const user = new User();
const copy2 = { ...user };
// copy2.greet(); // TypeError - Methode fehlt!
💡 Zusammenfassung:
... als REST sammelt Elemente (am Ende von Destructuring/Parametern). ... als SPREAD verteilt Elemente (in Arrays/Objekten/Aufrufen). Beachten Sie: Spread erstellt nur Shallow Copies!