Domů O mně Služby Portfolio Učím Blog Kontakt
← Zpět na učím

05.5 Destructuring objektů

Výuka

Proč destructuring?

Destructuring (destrukturalizace) je moderní syntaxe pro rozbalení hodnot z objektu do samostatných proměnných. Místo opakovaného přístupu přes tečku můžeš hodnoty "vytáhnout" přímo.

Proč to potřebujeme?

  • Čitelnost - Místo user.name, user.age použiješ pojmenované proměnné
  • Kratší kód - Jedna řádka místo několika přiřazení
  • Extrakce dat - Vytáhni jen to, co potřebuješ
  • Funkční parametry - Přijmi jen konkrétní vlastnosti objektu

Představ si to jako: Rozbalení balíčku. Místo "vezmi jméno z balíčku, vezmi věk z balíčku" říkáš "rozbal jméno a věk" - přiřadíš hodnoty přímo při rozbalování.

Jak to funguje?

Destructuring syntaxe:
const { key1, key2 } = objekt;

1. Levá strana = vzor (pattern) s názvy proměnných
2. Pravá strana = objekt
3. Hodnoty z objektu se přiřadí do proměnných podle NÁZVU klíče
4. key1 = objekt.key1, key2 = objekt.key2

Klíčové koncepty

  • Destructuring - rozbalení hodnot z objektu do proměnných
  • Pattern matching - vzor na levé straně odpovídá struktuře objektu
  • Názvy záleží - přiřazuje se podle názvu klíče, ne pořadí
  • Renaming - { oldName: newName } přejmenování proměnné
  • Default values - { key = default } výchozí hodnoty
  • Rest element ... - zbytek vlastností do objektu
  • Nested destructuring - vnořené rozbalení

JavaScript

Příklad 1: Základní destructuring

const user = {
  name: 'Alice',
  age: 25,
  city: 'Praha'
};

// Klasický způsob
const name = user.name;
const age = user.age;
console.log(name, age);
// → Alice 25

// S destructuring
const { name, age, city } = user;
console.log(name);  // → Alice
console.log(age);   // → 25
console.log(city);  // → Praha

Co se stalo?

  • { name, age, city } = user - vytvoř proměnné z objektu
  • name dostane user.name, age dostane user.age, atd.
  • Kratší a čitelnější než opakované user.name

Příklad 2: Částečné destructuring (vyber jen některé)

const person = {
  name: 'Bob',
  age: 30,
  city: 'Brno',
  email: 'bob@example.com',
  phone: '123456'
};

// Vyber jen name a email
const { name, email } = person;
console.log(name);   // → Bob
console.log(email);  // → bob@example.com

// Ostatní vlastnosti se ignorují
console.log(age);    // → ReferenceError: age is not defined

Co se stalo?

  • Můžeš vybrat jen některé vlastnosti
  • Ostatní vlastnosti se ignorují
  • Útečné pro extrakci jen potřebných dat

Příklad 3: Renaming (přejmenování proměnných)

const user = {
  name: 'Charlie',
  age: 35
};

// Přejmenování: { starýNázev: novýNázev }
const { name: userName, age: userAge } = user;

console.log(userName);  // → Charlie
console.log(userAge);   // → 35

// Původní názvy neexistují
// console.log(name);  // → ReferenceError: name is not defined

// Praktické použití - konflikt názvů
const product = {
  name: 'Laptop',
  price: 25000
};

const person = {
  name: 'David',
  age: 40
};

const { name: productName } = product;
const { name: personName } = person;

console.log(productName);  // → Laptop
console.log(personName);   // → David

Co se stalo?

  • Renaming: { oldName: newName }
  • Vytvoří proměnnou newName s hodnotou objekt.oldName
  • Užitečné pro konflikt názvů nebo lepší pojmenování

Příklad 4: Default values (výchozí hodnoty)

const user = {
  name: 'Eve',
  age: 28
};

// Bez default hodnoty - undefined
const { name, age, city } = user;
console.log(city);
// → undefined (city neexistuje v objektu)

// S default hodnotou
const { name: n, age: a, city: c = 'Neznámé město' } = user;
console.log(c);
// → Neznámé město (použije se default)

// Default hodnota se použije JEN pokud vlastnost je undefined
const user2 = {
  name: 'Frank',
  age: 35,
  city: null
};

const { city: city2 = 'Default' } = user2;
console.log(city2);
// → null (ne 'Default'! null !== undefined)

// Kombinace renaming a default
const { email: userEmail = 'no-email@example.com' } = user;
console.log(userEmail);
// → no-email@example.com

Co se stalo?

  • Default hodnota: { key = default }
  • Použije se jen když vlastnost je undefined (nebo neexistuje)
  • null, 0, '' jsou validní hodnoty - default se NEPOUŽIJE
  • Můžeš kombinovat s renaming: { oldName: newName = default }

Příklad 5: Rest element (...rest)

const user = {
  name: 'George',
  age: 40,
  city: 'Ostrava',
  email: 'george@example.com',
  phone: '123456'
};

// Vyber name, zbytek do objektu
const { name, ...rest } = user;
console.log(name);  // → George
console.log(rest);
// → { age: 40, city: 'Ostrava', email: 'george@example.com', phone: '123456' }

// Vyber name a age, zbytek ignoruj
const { name: n, age: a, ...others } = user;
console.log(n);      // → George
console.log(a);      // → 40
console.log(others);
// → { city: 'Ostrava', email: 'george@example.com', phone: '123456' }

// Rest musí být POSLEDNÍ
// const { ...all, name } = user;  // ❌ Syntax Error!

Co se stalo?

  • Rest element ...rest - zbývající vlastnosti do nového objektu
  • Musí být poslední (jinak syntax error)
  • Užitečné pro "některé a zbytek"

Příklad 6: Nested destructuring (vnořené objekty)

const user = {
  name: 'Helen',
  age: 30,
  address: {
    city: 'Praha',
    zip: '11000',
    street: 'Václavské náměstí'
  }
};

// Vnořené destructuring
const {
  name,
  address: { city, zip }
} = user;

console.log(name);  // → Helen
console.log(city);  // → Praha
console.log(zip);   // → 11000

// POZOR: address proměnná NEEXISTUJE
// console.log(address);  // → ReferenceError: address is not defined

// Pokud chceš i address objekt
const {
  name: userName,
  address,
  address: { city: userCity }
} = user;

console.log(userName);  // → Helen
console.log(address);   // → { city: 'Praha', zip: '11000', street: 'Václavské náměstí' }
console.log(userCity);  // → Praha

// Default hodnoty u vnořených objektů
const user2 = {
  name: 'Ivan'
  // address neexistuje
};

const {
  name: n,
  address: { city: c, zip: z } = {}
} = user2;

console.log(n);  // → Ivan
console.log(c);  // → undefined
console.log(z);  // → undefined

Co se stalo?

  • Nested destructuring: { prop: { nestedProp } }
  • Rozbalí vnořené objekty
  • Můžeš kombinovat s renaming a default values

TypeScript

TypeScript přidává typovou kontrolu destructuringu.

Stejné příklady s typy

// Interface pro destructuring
interface User {
  name: string;
  age: number;
  city?: string;
}

const user: User = {
  name: 'Alice',
  age: 25
};

// Destructuring s typy
const { name, age }: User = user;
// name: string, age: number

// TypeScript inferuje typy
const { name: userName, age: userAge } = user;
// userName: string, userAge: number (TypeScript ví!)

// Default hodnoty s typy
const { city = 'Praha' }: User = user;
// city: string (z default hodnoty)

// Rest element s typy
interface Person {
  name: string;
  age: number;
  email: string;
  phone: string;
}

const person: Person = {
  name: 'Bob',
  age: 30,
  email: 'bob@example.com',
  phone: '123456'
};

const { name, ...rest } = person;
// name: string
// rest: { age: number; email: string; phone: string }

// Nested destructuring s typy
interface Address {
  city: string;
  zip: string;
}

interface UserWithAddress {
  name: string;
  age: number;
  address: Address;
}

const userWithAddress: UserWithAddress = {
  name: 'Charlie',
  age: 35,
  address: {
    city: 'Brno',
    zip: '60200'
  }
};

const {
  name: n,
  address: { city, zip }
} = userWithAddress;
// n: string, city: string, zip: string

// Function parameters destructuring
function greet({ name, age }: User): string {
  return `Hi, I'm ${name}, ${age} years old`;
}

greet(user);  // ✅ OK

// greet({ name: 'David' });  // ❌ Error: Property 'age' is missing

// Optional properties
interface Config {
  host: string;
  port?: number;
  debug?: boolean;
}

function connect({ host, port = 3000, debug = false }: Config): void {
  console.log(`Connecting to ${host}:${port}, debug: ${debug}`);
}

connect({ host: 'localhost' });  // ✅ OK
connect({ host: 'localhost', port: 8080 });  // ✅ OK

TypeScript přidává:

  • Inference typů - TypeScript pozná typy proměnných
  • Kontrolu vlastností - musí existovat v interface
  • Kontrolu default hodnot - musí odpovídat typu
  • Prevenci chyb - upozorní na problém už při kompilaci

Rozdíl JS vs TS

JavaScript:

  • Destructuring funguje bez typové kontroly
  • Můžeš omylem destructurovat neexistující vlastnosti
  • Flexibilnější, ale nebezpečnější

TypeScript:

  • Destructuring má typovou kontrolu
  • TypeScript zkontroluje, že vlastnosti existují
  • Bezpečnější, prevence chyb
// JavaScript - projde, ale proměnné budou undefined
const user = { name: 'Alice', age: 25 };
const { name, age, email } = user;
console.log(email);  // → undefined

// TypeScript - upozorní
interface User {
  name: string;
  age: number;
}

const user: User = { name: 'Alice', age: 25 };
// const { name, age, email } = user;  // ❌ Error: Property 'email' does not exist on type 'User'

// Musíš použít optional nebo default
const { name, age, email = 'no-email' } = user;  // ✅ OK

Tip

💡 Používej destructuring v parametrech funkce:

// ❌ Špatně - musíš psát obj. všude
function greet(user) {
  return `Hi, I'm ${user.name}, ${user.age} years old`;
}

// ✅ Dobře - destructuring v parametru
function greet({ name, age }) {
  return `Hi, I'm ${name}, ${age} years old`;
}

// Ještě lepší - s default hodnotami
function greet({ name = 'Guest', age = 0 } = {}) {
  return `Hi, I'm ${name}, ${age} years old`;
}

💡 Rest pro "některé a zbytek" pattern:

const user = { name: 'Alice', age: 25, city: 'Praha', email: 'alice@example.com' };

// Vyber name, zbytek předej dál
const { name, ...userData } = user;
console.log('Name:', name);
updateUser(userData);  // Předej zbývající data

💡 Používej renaming pro lepší pojmenování:

// ❌ API vrací zkrácené názvy
const { n, a, c } = apiResponse;

// ✅ Přejmenuj na smysluplné názvy
const { n: name, a: age, c: city } = apiResponse;

Kvíz

Co vypíše tento kód?

const obj = {
  a: 1,
  b: 2,
  c: 3
};

const { a, ...rest } = obj;
console.log(rest.a);

- a je v samostatné proměnné, ne v rest

- - { a, ...rest } = obj - destructuring

  • a = obj.a = 1
  • ...rest = zbývající vlastnosti = { b: 2, c: 3 }
  • rest.a neexistuje (vlastnost a byla vybrána do samostatné proměnné)
  • rest.aundefined

- Není to chyba, jen vrací undefined

- rest.a je undefined, ne celý objekt

Důležité: Rest element ...rest obsahuje jen zbývající vlastnosti, ne ty, které byly explicitně destructurovány!

Důležité: Rest element ...rest obsahuje jen zbývající vlastnosti, ne ty, které byly explicitně destructurovány!

🎯 Závěrečný projekt

Po dokončení všech 8 dílů vytvoříte jednoduchou Todо aplikaci v čistém JavaScriptu. Naučíte se, jak aplikovat vše, co jste se naučili, na reálný projekt.

Zobrazit podrobnosti projektu →

Připraveni začít?

Zaregistrujte se a získejte přístup ke všem dílům tohoto seriálu

Kontaktujte mě

Informace o seriálu

Obtížnost

Délka

Cca 480 minut

Počet videí

8 videí + projekty

Certifikát

Po dokončení obdržíte certifikát


Lekce v této sekci


Struktura lekcí (souborový strom)

06. Typescript specifika
  • v přípravě
08. Moduly tridy
  • v přípravě
09. React zaklady
  • v přípravě
10. React hooks
  • v přípravě
12. Nextjs server
  • v přípravě
13. Databaze auth
  • v přípravě
14. Nextjs pokrocile
  • v přípravě