Scope v JavaScriptu

Česky by se scope dalo přeložit asi jako „rámec působnosti“. V JavaScriptu to zjednodušeně znamená odkud jsou jaké proměnné viditelné.

První tzv. globální scope (object Window) je automaticky v každém JS kódu. Vytvářením funkcí si můžeme snadno vytvořit další v tomto globálním.

var promenna = "Ahoj"; // Proměnná v globálním scope
var funkce = function() {
  var druhaPromenna = "Nazdar"; // Proměnná v lokálním scope funkce
}

Celé to funguje tak, že:

  1. Z globálního scope se nedostaneme k proměnné druhaPromenna.
  2. Z lokálního scope se ale k proměnné promenna nadřazeného globálního scope dostaneme.
  3. Uvnitř funkce funkce můžeme číst nebo měnit hodnotu promenna.
  4. Ale mimo naší funkci bude proměnná druhaPromenna nedostupná.

Zároveň nehrozí, že se proměnná uvnitř funkce omylem přepíše stejně nazvanou proměnnou z nadřazeného bloku (scope). To je asi hlavní výhoda a smysl.

Jednotlivá scope se do sebe mohou prakticky libovolně zanořovat — tj. vytvořit další funkci uvnitř další funkce atd. Pořád platí výše uvedená jednoduchá pravidla.

Nejjednodušší scope

V některých kódech hotových knihoven (nebo u uživatelských JS pro prohlížeče) můžeme pozorovat, že jsou obaleny nějak takto:

(function() {
  // vlastní kód
})();

To právě vytvoří nepojmenovanou funkci, která se rovnou zavolá, ale všechen kód se bude odehrávat ve vlastním privátním scope. Proto se na ukázce proměnná v globálním rámci nepřenastaví na jinou hodnotu.

Klíčové slovo this

Klíčové slovo this se hodí jako zkratka k nadřazenému objektu:

var objekt = {};
objekt.funkce = function() {
  // v this bude objekt
}
objekt.dalsiFunkce = function() {
  // zavolat předchozí funkci můžeme jako:
  // 1) objekt.funkce();
  // 2) this.funkce();
}

Často se to používá při nastavování (onNěco) událostí:

document.getElementById("tlacitko").onclick = function() {
  // nějaká akce
  // element, na který bylo kliknuto je v this
}

Ukázka.

Pozor, pokud v této funkci vytvoříme funkci další (zanoříme další scope), v this bude už něco jiného.

document.getElementById("tlacitko").onclick = function() {
  // v this je tlačítko
  var funkce = function() {
    // v this je globální scope (object Window)
  }
}

Řešení je si this uložit do lokální proměnné.

document.getElementById("tlacitko").onclick = function() {
  var tlacitko = this;
  var funkce = function() {
    // v proměnné tlacitko je tlačítko
  }
}

Číslo indexu v cyklu

Často potřebujeme nějaké sadě elementů přiřadit v cyklu akci a zároveň v té akci pracovat s indexem.

var odkazy = document.getElementsByTagName("a");
for (var i = 0; i < odkazy.length; i++) {
  odkazy[i].onclick = function() {
    alert(i);
  }
}

Uvedený kód možná trochu překvapivě u všech odkazů vypíše stejné číslo – index po posledním průchodu cyklem. Živá ukázka

Řešení je vytvořit další scope.

for (var i = 0; i < odkazy.length; i++) {
  odkazy[i].onclick = (function(cisloIndexu) {
    return function() {alert(cisloIndexu)};
  })(i)
}

Živá ukázka

To je všechno. Líbil se vám článek a chcete se dozvědět, až vyjde další?

Sledujte:

 

Připomínky mi pište do komentářů ↓

Fixní postranní panel

Jak vytvořit fixovaný banner?

JavaScriptové řešení prvku, který při rolování zůstane stále viditelný.

Úprava libovolného textu na stránce

Úprava textu stránky pomocí designMode

Jednoduchý bookmarklet pro okamžité přepsání libovolného textu na stránce.

Zablokování kláves

Zablokování některých kláves

Zablokování určitých kláves (šipek) pomocí JavaScriptu.

Aktivování/deaktivování okna

Zachycení aktivování a deaktivování okna v JS

V JavaScriptu lze relativně snadno reagovat na aktivování nebo deaktivování okna/záložky/tabu.

Baterka v CSS a JavaScriptu

Vytvoření efektu baterky v CSS a JS

Jak jednoduše vytvořit na stránce efekt baterky? Tedy ztmavit web a prohlížet ho jakýmsi průzorem.

Komentáře