03.08 Co je Scope
Výuka
Proč scope?
Představ si, že pracuješ na velkém projektu s tisíci řádků kódu. Co se stane, když vytvoříš proměnnou name? Co když někdo jiný už vytvořil proměnnou name někde jinde v kódu?
// Soubor 1
const name = "Alice";
// Soubor 2 (někdo jiný)
const name = "Bob"; // 💥 Konflikt!
Scope (oblast platnosti) řeší tento problém - určuje, kde je proměnná viditelná a kde ne.
Proč je to užitečné?
- Izolace - proměnné v jedné funkci "nevidí" proměnné v jiné
- Znovupoužitelnost - můžeš mít stejný název proměnné na více místech
- Organizace - kód je strukturovaný a přehledný
- Bezpečnost - náhodně nezmění hodnotu, kterou někdo jiný používá
Představ si to jako: Pokoje v domě. Co se děje v tvém pokoji (lokální scope), není viditelné v jiném pokoji. Ale všichni můžou používat společnou kuchyň (globální scope).
Jak to funguje?
Scope určuje, kde můžeš použít proměnnou:
1. Vytvoříš proměnnou v nějaké "oblasti" (funkce, blok, globálně)
2. Ta proměnná je viditelná jen v té oblasti a uvnitř vnořených oblastí
3. Mimo tu oblast proměnná "neexistuje"
4. JavaScript při hledání proměnné postupuje zevnitř ven (scope chain)
Tři hlavní typy scope:
- Globální scope - proměnná viditelná všude v programu
- Function scope - proměnná viditelná jen uvnitř funkce
- Block scope - proměnná viditelná jen uvnitř bloku
{}
Klíčové koncepty
- Scope = oblast viditelnosti - kde je proměnná "viditelná" a použitelná
- Lexical scope - scope určený kde kód píšeš, ne kde se spouští
- Scope chain - JavaScript hledá proměnnou nejdřív lokálně, pak v nadřazených scope
- Shadowing - vnitřní scope může "zakrýt" proměnnou z vnějšího scope
JavaScript
Příklad 1: Globální vs lokální scope
// Globální scope - viditelné všude
const globalName = "Alice";
function greet() {
// Lokální scope - viditelné jen uvnitř funkce
const localName = "Bob";
console.log(globalName); // ✅ Vidí globální
console.log(localName); // ✅ Vidí lokální
}
greet();
// → Alice
// → Bob
console.log(globalName); // ✅ Vidí globální
console.log(localName); // ❌ Error: localName is not defined
Co se stalo?
globalNameje v globálním scope - viditelná všudelocalNameje v function scope - viditelná jen uvnitřgreet()- Funkce vidí ven (vidí globální proměnné)
- Venku nevidíš dovnitř funkce (nemůžeš přistoupit k
localName)
Příklad 2: Vnořené scope (scope chain)
const level1 = "Globální";
function outer() {
const level2 = "Vnější funkce";
function inner() {
const level3 = "Vnitřní funkce";
console.log(level1); // ✅ Vidí globální
console.log(level2); // ✅ Vidí vnější funkci
console.log(level3); // ✅ Vidí vlastní scope
}
inner();
console.log(level1); // ✅ Vidí globální
console.log(level2); // ✅ Vidí vlastní scope
console.log(level3); // ❌ Error: level3 is not defined
}
outer();
console.log(level1); // ✅ Vidí globální
console.log(level2); // ❌ Error: level2 is not defined
Co se stalo?
- Funkce
inner()vidí všechny nadřazené scope: vlastní →outer()→ globální - Funkce
outer()nevidí dovnitřinner() - Globální scope nevidí dovnitř funkcí
- To se nazývá scope chain - řetězec hledání proměnných
Příklad 3: Block scope s let/const
const globalVar = "Globální";
function test() {
const functionVar = "Funkce";
if (true) {
const blockVar = "Blok";
console.log(globalVar); // ✅ Vidí globální
console.log(functionVar); // ✅ Vidí funkci
console.log(blockVar); // ✅ Vidí blok
}
console.log(globalVar); // ✅ Vidí globální
console.log(functionVar); // ✅ Vidí funkci
console.log(blockVar); // ❌ Error: blockVar is not defined
}
test();
Co se stalo?
letaconstvytváří block scope - viditelné jen v bloku{}- Bloky (if, for, while) také vytváří scope!
blockVarexistuje jen uvnitřifbloku
Příklad 4: var vs let/const (rozdíl ve scope)
function test() {
if (true) {
var varVariable = "var";
let letVariable = "let";
const constVariable = "const";
}
console.log(varVariable); // ✅ "var" (var ignoruje bloky!)
console.log(letVariable); // ❌ Error
console.log(constVariable); // ❌ Error
}
test();
Co se stalo?
varignoruje block scope - viditelná v celé funkciletaconstrespektují block scope - viditelné jen v bloku- Proto vždy používej
let/const, nevar!
Příklad 5: Shadowing (zakrývání proměnných)
const name = "Globální";
function greet() {
const name = "Lokální"; // "Zakryje" globální name
console.log(name); // → "Lokální" (použije lokální)
}
greet();
console.log(name); // → "Globální" (globální nezměněno)
Co se stalo?
- Lokální
namezakryje (shadow) globálnínameuvnitř funkce - Obě proměnné existují, ale lokální má přednost
- Globální
nameje nezměněná - jsou to dvě různé proměnné!
Příklad 6: Proč je scope užitečný
// ✅ Bez scope konfliktů - každá funkce má vlastní x
function double(x) {
return x * 2;
}
function triple(x) {
return x * 3;
}
console.log(double(5)); // → 10
console.log(triple(5)); // → 15
// Proměnné x v obou funkcích jsou RŮZNÉ - díky scope!
Co se stalo?
- Obě funkce mají parametr
x - Díky scope to není konflikt - každá funkce má vlastní
x - Bez scope by to byl chaos!
TypeScript
TypeScript respektuje stejná pravidla scope jako JavaScript. Scope funguje identicky!
// Globální scope
const globalMessage: string = "Viditelné všude";
function greet(name: string): void {
// Function scope
const greeting: string = "Hello";
if (name.length > 0) {
// Block scope
const fullGreeting: string = `${greeting}, ${name}!`;
console.log(fullGreeting);
}
// fullGreeting zde není viditelné
// console.log(fullGreeting); // ❌ Error
}
greet("Alice");
// greeting zde není viditelné
// console.log(greeting); // ❌ Error
TypeScript přidává:
- ✅ Stejná scope pravidla - žádný rozdíl oproti JavaScriptu
- ✅ Lepší chybové hlášky - TypeScript ti řekne, kde přesně se snažíš použít proměnnou mimo scope
- ✅ Kontrola typů v každém scope - typová bezpečnost funguje napříč všemi scope
Rozdíl JS vs TS
JavaScript:
const name = "Alice";
function test() {
console.log(name); // ✅ Funguje
console.log(age); // 💥 Runtime error: age is not defined
}
test();
TypeScript:
const name: string = "Alice";
function test(): void {
console.log(name); // ✅ Funguje
console.log(age); // ❌ Compile error: Cannot find name 'age'
}
test();
Rozdíl:
- JavaScript odhalí chybu při spuštění programu
- TypeScript odhalí chybu při psaní kódu - editor tě upozorní hned!
Tip
💡 Minimalizuj globální scope:
// ❌ Špatně - zbytečně globální
let counter = 0;
let message = "Hello";
function increment() {
counter++;
}
// ✅ Dobře - lokální scope
function createCounter() {
let counter = 0; // Lokální, izolované
return {
increment: () => counter++,
getValue: () => counter
};
}
const myCounter = createCounter();
💡 Používej const/let, ne var:
// ❌ var ignoruje block scope
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// → 3, 3, 3 (všechny vidí stejné i!)
// ✅ let respektuje block scope
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// → 0, 1, 2 (každá iterace má vlastní i!)
💡 Deklaruj proměnné co nejblíže použití:
// ❌ Špatně - proměnná daleko od použití
function processData() {
const result = [];
// ... 50 řádků kódu ...
result.push(data); // Kde byla result definována?
}
// ✅ Dobře - proměnná blízko použití
function processData() {
// ... kód ...
const result = [];
result.push(data); // Hned vidíš deklaraci
}
Kvíz
Co se stane, když zkusíš přistoupit k proměnné mimo její scope?
function test() {
const x = 5;
}
console.log(x);
❌ - x je lokální proměnná funkce, není viditelná venku
❌ - x neexistuje v globálním scope, není to undefined
✅ - JavaScript vyhodí chybu, protože x není definovaná v globálním scope
❌ - null musí být explicitně přiřazené, tady proměnná vůbec neexistuje
🎯 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
- 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
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ě