04.11 Spread operátor
Výuka
Proč Spread operátor?
Spread operátor ... "rozbalí" prvky pole (nebo iterable objektu) do jednotlivých hodnot. Je to moderní a elegantní způsob práce s poli.
Proč to potřebujeme?
- Kopírování pole - Rychlá a čistá kopie bez mutace
- Spojování polí - Sloučit více polí do jednoho
- Předávání argumentů - Rozbal pole jako argumenty funkce
- Immutability - Vytvoř nové pole místo změny originálu
Představ si to jako: Krabici s míčky. Spread operátor ... vysype všechny míčky z krabice ven (rozbalení). Místo jedné krabice máš jednotlivé míčky, se kterými můžeš dále pracovat.
Jak to funguje?
Spread operátor (...arr):
1. "Rozbalí" prvky pole do jednotlivých hodnot
2. [1, 2, 3] → 1, 2, 3
3. Používá se v místech, kde se očekává více hodnot:
- V novém poli: [...arr]
- Jako argumenty funkce: fn(...arr)
- Ve spojování polí: [...arr1, ...arr2]
Klíčové koncepty
- Spread operátor
...- rozbalí prvky pole do jednotlivých hodnot - Shallow copy - vytvoří kopii pole (pozor u objektů!)
- Immutability - neměnný způsob práce s poli
- Iterable - funguje s poli, stringy, Set, Map, apod.
- Rest parameter - opačný koncept (
...argsve funkci sbírá argumenty)
JavaScript
Příklad 1: Kopírování pole (shallow copy)
const original = [1, 2, 3];
// Kopie pomocí spread operátoru
const copy = [...original];
console.log(copy);
// → [1, 2, 3]
// Je to NOVÝ objekt
console.log(copy === original);
// → false (různé objekty)
// Změna kopie neovlivní originál
copy.push(4);
console.log(original); // → [1, 2, 3] (nezměněno)
console.log(copy); // → [1, 2, 3, 4]
Co se stalo?
[...original]vytvoří novou kopii pole- Kopie je samostatný objekt (jiná reference)
- Změny v kopii neovlivní originál
- Pozor: Shallow copy - objekty uvnitř se kopírují jako reference!
Příklad 2: Spojování polí (concatenation)
const arr1 = [1, 2];
const arr2 = [3, 4];
const arr3 = [5, 6];
// Spojení pomocí spread
const combined = [...arr1, ...arr2, ...arr3];
console.log(combined);
// → [1, 2, 3, 4, 5, 6]
// Můžeš přidat i další prvky
const extended = [0, ...arr1, 99, ...arr2, 100];
console.log(extended);
// → [0, 1, 2, 99, 3, 4, 100]
// Porovnání s concat()
const combined2 = arr1.concat(arr2, arr3);
console.log(combined2);
// → [1, 2, 3, 4, 5, 6] (stejný výsledek)
Co se stalo?
[...arr1, ...arr2]sloučí pole do jednoho nového- Můžeš kombinovat více polí a další prvky
- Čitelnější než
concat()
Příklad 3: Přidání prvků immutabilně
const numbers = [2, 3, 4];
// Přidej na začátek (immutabilně)
const withFirst = [1, ...numbers];
console.log(withFirst);
// → [1, 2, 3, 4]
// Přidej na konec (immutabilně)
const withLast = [...numbers, 5];
console.log(withLast);
// → [2, 3, 4, 5]
// Přidej uprostřed
const withMiddle = [...numbers.slice(0, 2), 99, ...numbers.slice(2)];
console.log(withMiddle);
// → [2, 3, 99, 4]
// Originál zůstal netknutý
console.log(numbers);
// → [2, 3, 4]
Co se stalo?
- Spread vytváří nová pole bez mutace originálu
- Vhodné pro React/Redux (immutabilní state)
- Alternativa k
push,unshift,splice
Příklad 4: Předávání argumentů funkci
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
// Bez spread - předáš pole (nefunguje)
console.log(sum(numbers));
// → NaN (numbers je pole, ne 3 čísla)
// Se spread - rozbal pole na argumenty
console.log(sum(...numbers));
// → 6 (ekvivalentní sum(1, 2, 3))
// Praktický příklad - Math.max
const nums = [10, 5, 30, 15];
console.log(Math.max(...nums));
// → 30 (Math.max nemá verzi pro pole!)
Co se stalo?
...numbersrozbalí pole[1, 2, 3]na1, 2, 3- Funkce dostane jednotlivé argumenty, ne pole
- Užitečné pro funkce, které očekávají více argumentů
Příklad 5: Spread s řetězci (string je iterable)
const text = 'hello';
// Rozbal string na pole znaků
const chars = [...text];
console.log(chars);
// → ['h', 'e', 'l', 'l', 'o']
// Porovnej s Array.from()
const chars2 = Array.from(text);
console.log(chars2);
// → ['h', 'e', 'l', 'l', 'o'] (stejný výsledek)
// Spread funguje s jakýmkoli iterable
const set = new Set([1, 2, 3]);
const arrFromSet = [...set];
console.log(arrFromSet);
// → [1, 2, 3]
Co se stalo?
- Spread funguje s jakýmkoli iterable objektem
- String, pole, Set, Map, atd.
- Rychlý způsob převodu na pole
Příklad 6: Shallow copy - pozor u objektů!
const arr = [{ name: 'Alice' }, { name: 'Bob' }];
// Shallow copy
const copy = [...arr];
// Změň objekt v kopii
copy[0].name = 'Charlie';
// Originál SE ZMĚNIL! (objekty se kopírují jako reference)
console.log(arr[0].name);
// → Charlie (POZOR!)
// Deep copy - musíš použít jiné metody
const deepCopy = JSON.parse(JSON.stringify(arr)); // Deep copy
deepCopy[1].name = 'David';
console.log(arr[1].name);
// → Bob (nezměněno)
Co se stalo?
- Spread vytváří shallow copy - kopíruje jen první úroveň
- Objekty uvnitř pole se kopírují jako reference
- Pro deep copy použij
JSON.parse(JSON.stringify())nebo knihovnu (lodash)
TypeScript
TypeScript přidává typovou kontrolu a readonly pole.
Stejné příklady s typy
// Kopírování s typy
const original: number[] = [1, 2, 3];
const copy: number[] = [...original];
// Spojování s typy
const arr1: number[] = [1, 2];
const arr2: number[] = [3, 4];
const combined: number[] = [...arr1, ...arr2];
// Můžeš kombinovat různé typy
const nums: number[] = [1, 2];
const strs: string[] = ['a', 'b'];
const mixed: (number | string)[] = [...nums, ...strs]; // [1, 2, 'a', 'b']
// Objekty s interface
interface User {
name: string;
age: number;
}
const users: User[] = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 }
];
const copy: User[] = [...users];
// Readonly pole - můžeš použít spread pro kopii
const readonly: readonly number[] = [1, 2, 3];
const mutable: number[] = [...readonly]; // ✅ OK - kopie je mutovatelná
// Spread s generickým typem
function clone<T>(arr: T[]): T[] {
return [...arr];
}
const cloned: number[] = clone([1, 2, 3]);
// Chybová kontrola - musí být iterable
const obj = { a: 1, b: 2 };
// const arr = [...obj]; // ❌ Error: Type '{ a: number; b: number; }' is not an array type or a string type
// Spread u objektů funguje (ES2018+)
const objCopy = { ...obj }; // ✅ OK - { a: 1, b: 2 }
TypeScript přidává:
- ✅ Typovou kontrolu - spread musí být použit na iterable
- ✅ Inference typů - TypeScript pozná typ výsledku
- ✅ Readonly kontrolu - můžeš vytvořit mutovatelnou kopii z readonly pole
- ✅ Generické funkce - typově bezpečné utility funkce
Rozdíl JS vs TS
JavaScript:
- Spread funguje bez typové kontroly
- Můžeš omylem použít spread na ne-iterable
- Flexibilnější, ale nebezpečnější
TypeScript:
- Spread je typově kontrolovaný
- TypeScript zkontroluje, že používáš spread na iterable
- Bezpečnější, prevence chyb
// JavaScript - runtime error
const obj = { a: 1, b: 2 };
const arr = [...obj]; // TypeError: obj is not iterable
// TypeScript - compile error
const obj = { a: 1, b: 2 };
const arr = [...obj]; // ❌ Error: Type is not an array type or a string type
Tip
💡 Používej spread pro immutabilní operace:
// ❌ Mutace originálu
const arr = [1, 2, 3];
arr.push(4);
// ✅ Immutabilní přidání
const newArr = [...arr, 4];
// ✅ Vhodné pro React state
setState([...state, newItem]);
💡 Spread je shallow copy - pozor u objektů:
const arr = [{ x: 1 }];
// ❌ Shallow copy - objekty se kopírují jako reference
const copy = [...arr];
copy[0].x = 2; // Změní i originál!
// ✅ Deep copy
const deepCopy = JSON.parse(JSON.stringify(arr));
💡 Spread vs concat - čitelnost:
// ❌ Méně čitelné
const result = arr1.concat(arr2).concat(arr3);
// ✅ Čitelnější
const result = [...arr1, ...arr2, ...arr3];
Kvíz
Co vypíše tento kód?
const arr1 = [1, 2];
const arr2 = [...arr1, 3];
arr2.push(4);
console.log(arr1.length);
✅ - [...arr1, 3] vytvoří NOVÉ pole [1, 2, 3] (kopie arr1 + prvek 3). arr2.push(4) přidá prvek do arr2, ale NEOVLIVNÍ arr1, protože jsou to různé objekty. arr1 stále obsahuje [1, 2], tedy délka je 2
❌ - arr1 se nezměnilo
❌ - Délka arr2 je 4, ne arr1
❌ - Kód je validní
Důležité: Spread operátor vytváří novou kopii, takže změny v kopii neovlivní originál!
Důležité: Spread operátor vytváří novou kopii, takže změny v kopii neovlivní originál!
🎯 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 →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
- 04.01 Vytvoření pole
- 04.02 Přístup k prvkům
- 04.03 Push, pop, shift, unshift
- 04.04 Slice a splice
- 04.06 Filter
- 04.07 Reduce
- 04.08 Find a findIndex
- 04.09 Some a every
- 04.10 Sort
- 04.11 Spread operátor
- 04.12 Set
- 04.13 Map kolekce
- 04.14 Destructuring polí
Struktura lekcí (souborový strom)
- 1.1 Úvod do JavaScriptu a TypeScriptu
- 1.2 Nastavení prostředí
- 1.3 První program
- 1.4 Proměnné: var, let, const
- 1.5 Datové typy - přehled
- 1.6 String (řetězce)
- 1.7 Number (čísla)
- 1.8 Boolean (pravda/nepravda)
- 1.9 Null a Undefined
- 1.10 Type Inference vs Annotations
- 1.11 Aritmetické operátory
- 1.12 Porovnávací operátory
- 1.13 Logické operátory
- 1.14 Komentáře
- 1.15 Console metody
- 03.01 Deklarace funkce
- 03.02 Function Expression
- 03.03 Arrow Functions
- 03.04 Parametry a argumenty
- 03.05 Return hodnoty
- 03.06 Výchozí parametry
- 03.07 Rest parametry
- 03.08 Co je Scope
- 03.09 Lexikální Scope
- 03.10 Řetězec Scope
- 03.11 Globální Scope
- 03.12 Životní Cyklus Proměnných
- 03.13 Omezení Scope
- 03.14 Použití Closures
- 03.15 Callback funkce
- 03.16 Higher-order Functions
- 03.17 IIFE
- 03.18 Void funkce
- 03.19 Rekurze
- v přípravě
- v přípravě
- v přípravě
- v přípravě
- 01 — Co je Next.js
- 02 — Vytvoření projektu
- 03 — Struktura projektu (app/)
- 04 — Page komponenty (page.js / page.tsx)
- 05 — Layout komponenty (layout.js / layout.tsx)
- 06 — File-based routing
- 07 — Dynamické routy ([id]/page.js)
- 08 — Link komponenta (navigace)
- 09 — Image komponenta (next/image)
- 10 — Metadata (title, description, Open Graph)
- 11 — Loading UI (loading.js / loading.tsx)
- 12 — Error handling (error.js / error.tsx)
- 13 — Not Found (not-found.js / not-found.tsx)
- v přípravě
- v přípravě
- v přípravě