11. března 2026

Destrukturační přiřazení

Dvě nejpoužívanější datové struktury v JavaScriptu jsou objekty a pole.

  • Objekty nám umožňují vytvořit jednoduchou entitu, v níž jsou datové prvky uloženy pod klíči.
  • Pole nám umožňují shromáždit datové prvky do seřazeného seznamu.

Když je však předáváme nějaké funkci, nemusíme je potřebovat celé. Funkce může požadovat jen určité prvky nebo vlastnosti.

Destrukturační přiřazení je speciální syntaxe, která nám umožňuje „rozbalit“ pole nebo objekty do svazku proměnných, což bývá někdy vhodnější.

Destrukturace také skvěle funguje se složitými funkcemi, které mají spoustu parametrů, standardní hodnoty a tak dále. Brzy to uvidíme.

Destrukturace polí

Zde je příklad, jak je pole destrukturováno do proměnných:

// máme pole obsahující jméno a příjmení
let pole = ["Jan", "Novák"]

// destrukturační přiřazení
// nastaví křestníJméno = pole[0]
// a příjmení = pole[1]
let [křestníJméno, příjmení] = pole;

alert(křestníJméno); // Jan
alert(příjmení);  // Novák

Nyní můžeme místo s prvky pole pracovat s proměnnými.

Vypadá to výborně, když to zkombinujeme se split nebo jinými metodami vracejícími pole:

let [křestníJméno, příjmení] = "Jan Novák".split(' ');
alert(křestníJméno); // Jan
alert(příjmení);  // Novák

Jak vidíte, syntaxe je jednoduchá. Je tady však několik zvláštních detailů. Podíváme se na další příklady, abychom tomu lépe porozuměli.

„Destrukturace“ neznamená „destrukce“

Tato technika se nazývá „destrukturační přiřazení“, protože provádí „destrukturaci“ kopírováním prvků do proměnných. Samotné pole se však nemění.

Je to jen kratší způsob, jak napsat:

// let [křestníJméno, příjmení] = pole;
let křestníJméno = pole[0];
let příjmení = pole[1];
Ignorování prvků pomocí čárek

Nechtěné prvky pole můžeme zahodit přidáním čárky:

// druhý prvek nepotřebujeme
let [křestníJméno, , titul] = ["Julius", "Caesar", "Konzul", "Římské republiky"];

alert( titul ); // Konzul

V uvedeném kódu byl druhý prvek pole přeskočen, třetí přiřazen do proměnné titul a ostatní prvky pole byly také přeskočeny (protože pro ně nejsou uvedeny žádné proměnné).

Funguje s libovolným iterovatelným objektem na pravé straně

…Ve skutečnosti můžeme destrukturační přiřazení použít na libovolný iterovatelný objekt, nejenom na pole:

let [a, b, c] = "abc"; // ["a", "b", "c"]
let [jedna, dvě, tři] = new Set([1, 2, 3]);

To funguje, protože vnitřně se destrukturační přiřazení vykonává iterací nad hodnotou vpravo. Je to určitý druh syntaktického cukru pro volání for..of nad hodnotou vpravo od = a přiřazení hodnot.

Na levé straně můžeme přiřazovat do čehokoli

Na levé straně můžeme používat cokoli, do čeho lze přiřazovat.

Například vlastnost objektu:

let uživatel = {};
[uživatel.křestníJméno, uživatel.příjmení] = "Jan Novák".split(' ');

alert(uživatel.křestníJméno); // Jan
alert(uživatel.příjmení); // Novák
Cyklus pomocí .entries()

V předchozí kapitole jsme viděli metodu Object.entries(obj).

Můžeme ji používat společně s destrukturací k procházení dvojic klíčů a hodnot objektu:

let uživatel = {
  jméno: "Jan",
  věk: 30
};

// cyklus nad dvojicemi klíč-hodnota
for (let [klíč, hodnota] of Object.entries(uživatel)) {
  alert(`${klíč}:${hodnota}`); // jméno:Jan, poté věk:30
}

Podobný kód pro Map je jednodušší, protože mapa je iterovatelná:

let uživatel = new Map();
uživatel.set("jméno", "Jan");
uživatel.set("věk", "30");

// Map iteruje nad dvojicemi [klíč, hodnota], což je velmi vhodné pro destrukturaci
for (let [klíč, hodnota] of uživatel) {
  alert(`${klíč}:${hodnota}`); // jméno:Jan, poté věk:30
}
Trik pro výměnu proměnných

Existuje dobře známý trik pro výměnu hodnot dvou proměnných použitím destrukturačního přiřazení:

let host = "Jana";
let správce = "Petr";

// Vyměníme hodnoty: učiníme host=Petr, správce=Jana
[host, správce] = [správce, host];

alert(`${host} ${správce}`); // Petr Jana (úspěšně vyměněno!)

Zde jsme vytvořili dočasné pole dvou proměnných a okamžitě je destrukturovali v obráceném pořadí.

Tímto způsobem můžeme vyměnit i více než dvě proměnné.

Zbytek „…“

Jestliže je pole delší než seznam nalevo, „přebývající“ prvky jsou obvykle vypuštěny.

Například zde se vezmou jen první dva prvky a ostatní se jednoduše ignorují:

let [jméno1, jméno2] = ["Julius", "Caesar", "Konzul", "Římské republiky"];

alert(jméno1); // Julius
alert(jméno2); // Caesar
// Další prvky již nejsou nikam přiřazeny

Kdybychom chtěli shromáždit i to, co následuje, můžeme přidat jeden další parametr, do něhož se uloží „zbytek“, pomocí tří teček "...":

let [jméno1, jméno2, ...zbytek] = ["Julius", "Caesar", "Konzul", "Římské republiky"];

// zbytek je pole prvků počínaje třetím
alert(zbytek[0]); // Konzul
alert(zbytek[1]); // Římské republiky
alert(zbytek.length); // 2

Hodnota proměnné zbytek je pole zbývajících prvků pole.

Místo zbytek můžeme použít jakékoli jméno proměnné, jen musíme zajistit, aby před ním byly tři tečky a aby bylo v destrukturačním přiřazení uvedeno jako poslední.

let [jméno1, jméno2, ...tituly] = ["Julius", "Caesar", "Konzul", "Římské republiky"];
// nyní tituly = ["Konzul", "Římské republiky"]

Standardní hodnoty

Pokud je pole kratší než seznam proměnných nalevo, nedojde k chybě. Neuvedené hodnoty se považují za nedefinované:

let [křestníJméno, příjmení] = [];

alert(křestníJméno); // undefined
alert(příjmení); // undefined

Chceme-li, aby chybějící hodnoty nahradila nějaká „standardní“ hodnota, můžeme ji uvést pomocí =:

// standardní hodnoty
let [jméno = "Host", příjmení = "Anonym"] = ["Julius"];

alert(jméno);    // Julius (z pole)
alert(příjmení); // Anonym (použita standardní hodnota)

Standardními hodnotami mohou být i složitější výrazy nebo dokonce volání funkcí. Vyhodnocují se jen tehdy, když hodnota není poskytnuta.

Například zde použijeme pro dvě standardní hodnoty funkci prompt:

// spustí prompt jen pro příjmení
let [jméno = prompt('jméno?'), příjmení = prompt('příjmení?')] = ["Julius"];

alert(jméno);    // Julius (z pole)
alert(příjmení); // to, co vrátil prompt

Prosíme všimněte si: prompt se spustí jen pro chybějící hodnotu (příjmení).

Destrukturace objektů

Destrukturační přiřazení funguje i pro objekty.

Základní syntaxe je:

let {proměnná1, proměnná2} = {proměnná1:…, proměnná2:…}

Na pravé straně bychom měli mít existující objekt, který chceme rozdělit do proměnných. Levá strana obsahuje objektu podobný „vzor“ pro odpovídající vlastnosti. V nejjednodušším případě je to seznam názvů proměnných v {...}.

Příklad:

let možnosti = {
  titulek: "Menu",
  šířka: 100,
  výška: 200
};

let {titulek, šířka, výška} = možnosti;

alert(titulek); // Menu
alert(šířka);   // 100
alert(výška);   // 200

Vlastnosti možnosti.titulek, možnosti.šířka a možnosti.výška jsou přiřazeny do příslušných proměnných.

Na pořadí nezáleží. Tohle bude fungovat také:

// změníme pořadí v let {...}
let {výška, šířka, titulek} = { titulek: "Menu", výška: 200, šířka: 100 }

Vzor na levé straně může být složitější a může specifikovat mapování mezi vlastnostmi a proměnnými.

Chceme-li přiřadit vlastnost do proměnné s jiným názvem, např. přiřadit možnosti.šířka do proměnné jménem š, pak můžeme nastavit jméno proměnné za dvojtečkou:

let možnosti = {
  titulek: "Menu",
  šířka: 100,
  výška: 200
};

// { zdrojováVlastnost: cílováProměnná }
let {šířka: š, výška: v, titulek} = možnosti;

// šířka -> š
// výška -> v
// titulek -> titulek

alert(titulek); // Menu
alert(š);       // 100
alert(v);       // 200

Dvojtečka ukazuje, „co : jde kam“. V uvedeném příkladu vlastnost šířka jde do š, vlastnost výška jde do v a titulek se přiřadí do proměnné se stejným názvem.

Pro vlastnosti, které mohou chybět, můžeme nastavit standardní hodnoty pomocí "=" takto:

let možnosti = {
  titulek: "Menu"
};

let {šířka = 100, výška = 200, titulek} = možnosti;

alert(titulek);  // Menu
alert(šířka);    // 100
alert(výška);    // 200

Stejně jako u polí nebo parametrů funkcí mohou standardní hodnoty být libovolné výrazy nebo dokonce volání funkcí. Budou vyhodnoceny jen tehdy, když hodnota nebude poskytnuta.

V následujícím kódu se prompt zeptá na proměnnou šířka, ale ne na titulek:

let možnosti = {
  titulek: "Menu"
};

let {šířka = prompt("šířka?"), titulek = prompt("titulek?")} = možnosti;

alert(titulek); // Menu
alert(šířka);   // (to, co vrátil prompt)

Můžeme také zkombinovat dvojtečku a rovnítko:

let možnosti = {
  titulek: "Menu"
};

let {šířka: š = 100, výška: v = 200, titulek} = možnosti;

alert(titulek);  // Menu
alert(š);        // 100
alert(v);        // 200

Máme-li složitý objekt s mnoha vlastnostmi, můžeme vytáhnout jen ty, které potřebujeme:

let možnosti = {
  titulek: "Menu",
  šířka: 100,
  výška: 200
};

// do proměnné vyjmeme jen titulek
let { titulek } = možnosti;

alert(titulek); // Menu

Zbytkový vzor „…“

Co když má objekt více vlastností, než my máme proměnných? Můžeme některé z nich vzít a „zbytek“ někam přiřadit?

Můžeme použít zbytkový vzor, stejně jako jsme to udělali u polí. Některé starší prohlížeče to nepodporují (IE, jako polyfill použijte Babel), ale v moderních to funguje.

Vypadá to takto:

let možnosti = {
  titulek: "Menu",
  výška: 200,
  šířka: 100
};

// titulek = vlastnost nazvaná titulek
// zbytek = objekt s ostatními vlastnostmi
let {titulek, ...zbytek} = možnosti;

// nyní titulek="Menu", zbytek={výška: 200, šířka: 100}
alert(zbytek.výška); // 200
alert(zbytek.šířka); // 100
Chyták při neuvedení let

Ve výše uvedených příkladech jsme proměnné deklarovali přímo při přiřazení: let {…} = {…}. Můžeme samozřejmě použít i existující proměnné bez uvedení let. Je tady však chyták.

Tohle nebude fungovat:

let titulek, šířka, výška;

// na tomto řádku je chyba
{titulek, šířka, výška} = {titulek: "Menu", šířka: 200, výška: 100};

Problém je v tom, že JavaScript zachází s {...} v hlavním kódu (ne uvnitř jiného výrazu) jako s kódovým blokem. Takové kódové bloky můžeme používat k seskupení příkazů, například:

{
  // kódový blok
  let zpráva = "Ahoj";
  // ...
  alert( zpráva );
}

Zde tedy JavaScript předpokládá, že máme kódový blok, což je důvod, proč nastane chyba. My místo toho chceme destrukturaci.

Abychom sdělili JavaScriptu, že tohle není kódový blok, můžeme uzavřít výraz do závorek (...):

let titulek, šířka, výška;

// nyní je to v pořádku
({titulek, šířka, výška} = {titulek: "Menu", šířka: 200, výška: 100});

alert( titulek ); // Menu

Vnořená destrukturace

Jestliže objekt nebo pole obsahuje jiné vnořené objekty a pole, můžeme vyjmout hlubší části pomocí složitějších vzorů na levé straně.

V následujícím kódu objekt možnosti obsahuje jiný objekt ve vlastnosti velikost a pole ve vlastnosti prvky. Vzor na levé straně přiřazení má stejnou strukturu jako objekt, z něhož vybíráme hodnoty:

let možnosti = {
  velikost: {
    šířka: 100,
    výška: 200
  },
  prvky: ["Koláč", "Vdolek"],
  extra: true
};

// destrukturační přiřazení, pro čitelnost rozdělené do více řádků
let {
  velikost: { // zde uvedeme velikost
    šířka,
    výška
  },
  prvky: [prvek1, prvek2], // zde přiřadíme prvky
  titulek = "Menu" // v objektu není přítomen (použije se standardní hodnota)
} = možnosti;

alert(titulek); // Menu
alert(šířka);   // 100
alert(výška);   // 200
alert(prvek1);  // Koláč
alert(prvek2);  // Vdolek

Do příslušných proměnných se přiřadí všechny vlastnosti objektu možnosti s výjimkou extra, která v levé části chybí:

Nakonec tedy máme šířka, výška, prvek1, prvek2 a titulek ze standardní hodnoty.

Všimněte si, že zde nejsou žádné proměnné pro velikost a prvky, jelikož jsme místo nich vzali jejich obsah.

Chytré funkční parametry

Stává se, že funkce má mnoho parametrů a většina z nich je nepovinná. To platí zejména pro uživatelská rozhraní. Představte si funkci, která vytváří menu. Může obsahovat šířku, výšku, titulek, seznam prvků a podobně.

Zde je špatný způsob, jak takovou funkci napsat:

function zobrazMenu(titulek = "Bez názvu", šířka = 200, výška = 100, prvky = []) {
  // ...
}

Problém v reálném životě spočívá v tom, jak si pamatovat pořadí argumentů. IDE se nám s tím obvykle snaží pomoci, zvláště je-li kód dobře dokumentován, ale i tak… Další problém je v tom, jak volat funkci, když u většiny parametrů chceme ponechat standardní hodnoty.

Takhle?

// undefined tam, kde se má použít standardní hodnota
zobrazMenu("Moje menu", undefined, undefined, ["Prvek1", "Prvek2"])

To je ošklivé. A když budeme pracovat s více parametry, bude to nečitelné.

Destrukturace nás přichází zachránit!

Můžeme předávat parametry jako objekt a funkce je okamžitě destrukturuje do proměnných:

// předáme objekt do funkce
let možnosti = {
  titulek: "Moje menu",
  prvky: ["Prvek1", "Prvek2"]
};

// ...a ta jej okamžitě rozdělí do proměnných
function zobrazMenu({titulek = "Bez názvu", šířka = 200, výška = 100, prvky = []}) {
  // titulek, prvky – převzaty z objektu možnosti,
  // šířka, výška – použity standardní hodnoty
  alert( `${titulek} ${šířka} ${výška}` ); // Moje menu 200 100
  alert( prvky ); // Prvek1,Prvek2
}

zobrazMenu(možnosti);

S vnořenými objekty a dvojtečkovým mapováním můžeme použít i složitější destrukturaci:

let možnosti = {
  titulek: "Moje menu",
  prvky: ["Prvek1", "Prvek2"]
};

function zobrazMenu({
  titulek = "Bez názvu",
  šířka: š = 100, // šířka jde do š
  výška: v = 200, // výška jde do v
  prvky: [prvek1, prvek2] // první prvek pole prvky jde do prvek1, druhý do prvek2
}) {
  alert( `${titulek} ${š} ${v}` ); // Moje menu 100 200
  alert( prvek1 ); // Prvek1
  alert( prvek2 ); // Prvek2
}

zobrazMenu(možnosti);

Úplná syntaxe je stejná jako u destrukturačního přiřazení:

function({
  vstupujícíVlastnost: názevProměnné = standardníHodnota
  ...
})

Pro objekt parametrů pak budeme mít pro vlastnost vstupujícíVlastnost proměnnou názevProměnné , jejíž standardní hodnotou bude standardníHodnota.

Prosíme všimněte si, že taková destrukturace předpokládá, že zobrazMenu() má argument. Chceme-li všechny hodnoty standardní, měli bychom uvést prázdný objekt:

zobrazMenu({}); // ok, všechny hodnoty jsou standardní

zobrazMenu(); // tohle ohlásí chybu

To můžeme opravit tak, že učiníme {} standardní hodnotou celého objektu parametrů:

function zobrazMenu({ titulek = "Menu", šířka = 100, výška = 200 } = {}) {
  alert( `${titulek} ${šířka} ${výška}` );
}

zobrazMenu(); // Menu 100 200

V uvedeném kódu je celý argumentový objekt standardně {}, takže vždy bude co destrukturovat.

Shrnutí

  • Destrukturační přiřazení umožňuje rychlé mapování objektu nebo pole do mnoha proměnných.

  • Úplná syntaxe pro objekt:

    let {vlastnost : názevProměnné = standardníHodnota, ...zbytek} = objekt

    To znamená, že vlastnost vlastnost má přijít do proměnné názevProměnné, a pokud taková vlastnost neexistuje, měla by se použít hodnota standardníHodnota.

    Objektové vlastnosti, pro které není uvedeno mapování, se zkopírují do objektu zbytek.

  • Úplná syntaxe pro pole:

    let [prvek1 = standardníHodnota, prvek2, ...zbytek] = pole

    První prvek se uloží do proměnné prvek1, druhý do prvek2, ze všech ostatních prvků se vytvoří pole zbytek.

  • Je možné extrahovat data z vnořených polí nebo objektů. V tom případě musí mít levá strana stejnou strukturu jako pravá.

Úlohy

důležitost: 5

Máme objekt:

let uživatel = {
  jméno: "Jan",
  roky: 30
};

Napište destrukturační přiřazení, které načte:

  • vlastnost jméno do proměnné jméno.
  • vlastnost roky do proměnné věk.
  • vlastnost jeSprávce do proměnné jeSprávce (false, pokud taková vlastnost není).

Zde je příklad hodnot po vašem přiřazení:

let uživatel = { jméno: "Jan", roky: 30 };

// váš kód na levé straně:
// ... = uživatel

alert( jméno ); // Jan
alert( věk ); // 30
alert( jeSprávce ); // false
let uživatel = {
  jméno: "Jan",
  roky: 30
};

let {jméno, roky: věk, jeSprávce = false} = uživatel;

alert( jméno ); // Jan
alert( věk ); // 30
alert( jeSprávce ); // false
důležitost: 5

Máme objekt platy:

let platy = {
  "Jan": 100,
  "Petr": 300,
  "Marie": 250
};

Vytvořte funkci nejvyššíPlat(platy), která vrátí jméno nejlépe placené osoby.

  • Je-li objekt platy prázdný, měla by vrátit null.
  • Jestliže je nejlépe placených osob více, může vrátit libovolnou z nich.

P.S. K iteraci nad dvojicemi klíč/hodnota použijte Object.entries a destrukturaci.

Otevřít pískoviště s testy.

function nejvyššíPlat(platy) {

  let maxPlat = 0;
  let maxJméno = null;

  for(const [jméno, plat] of Object.entries(platy)) {
    if (maxPlat < plat) {
      maxPlat = plat;
      maxJméno = jméno;
    }
  }

  return maxJméno;
}

Otevřít řešení s testy na pískovišti.

Mapa tutoriálu

Komentáře

přečtěte si před komentováním…
  • Máte-li návrhy na zlepšení, vytvořte prosím issue na GitHubu nebo pull request místo komentáře.
  • Pokud v článku něčemu nerozumíte, napište prosím, čemu přesně a na kterém místě.
  • Pro vložení několika slov kódu použijte značku <code>, pro několik řádků je obalte značkou <pre>, pro více než 10 řádků vložte odkaz na pískoviště (plnkr, jsbin, codepen…)