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

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  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?

  • globalName je v globálním scope - viditelná všude
  • localName je 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?

  • let a const vytváří block scope - viditelné jen v bloku {}
  • Bloky (if, for, while) také vytváří scope!
  • blockVar existuje jen uvnitř if bloku

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?

  • var ignoruje block scope - viditelná v celé funkci
  • let a const respektují block scope - viditelné jen v bloku
  • Proto vždy používej let/const, ne var!

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í name zakryje (shadow) globální name uvnitř funkce
  • Obě proměnné existují, ale lokální má přednost
  • Globální name je 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 →

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ě