Keď som pred niekoľkými rokmi začal študovať programovanie v JavaScripte, pamätám si, ako som v jednej knihe narazil prvýkrát na pojem Closure. Autor hneď na začiatku tvrdil, že ak ste programátor zo sveta objektového programovania, budete mať problém to pochopiť (česi na to majú výborný výraz: „půjde vám z toho hlava kolem“). No, myslím že nebol ďaleko od pravdy. Ani po tej dobe nie je Closure pre mňa jednoduchá téma, a aj preto som hneď po zhliadnutí názvu knihy You dont know JS: Scope & Closure od Kyle Simpsona vedel, že je pre mňa. Tak nejako ten názov vyjadroval moje pocity k tejto téme 🙂
Kniha má len 98 strán a ak sa chcete naučiť programovať v JavaScripte, tak to nie je kniha pre vás. Nepopisuje jazyk ako celok, ale zameriava sa len na Scope a Closure. Je to kniha z edície, kde všetky začínajú tým „You dont know JS“. Je to preto, lebo veľká časť ľudí, ktorá JavaScript používa, ho naozaj dobré nepozná. Je to syndróm, ktorý sa začína viac a viac objavovať ako sa postupne použitie JavaScriptu rozrastá. Aj sám autor tvrdí, že je to preto, lebo JavaScript sa dá používať bez toho, aby ste vedeli, čo to Scope a Closure je. Stačí, keď sa naučíte volať API nejakej JavaScript knižnice. A ja musím potvrdiť, že poznám veľa programátorov, ktorí boli dotlačení k tomu, aby v nejakej miere používali JavaScript, ale poznajú ho naozaj len z pohľadu používateľa API.
Takže Scope a Closure. To sú témy, ktoré spolu úzko súvia. Scope je rozsah platnosti premennej. Inak povedané, ak ju na nejakom mieste zadefinujete, určuje kde všade ju viete používať. To vôbec nie je žiadna novinka, lebo väčšina mainstreamových jazykov ako je Java, C# alebo C++ to majú tiež. JavaScript má síce niekoľko špeciálnych príkazov, ktoré so scopom umožňujú manipulovať, ale tie sa používajú dosť raritne. Takže väčšinou platí základné pravidlo, že ak ste v nejakom bloku kódu, tak máte prístupné všetky premenné definované v rodičovských blokoch, a k tomu samozrejme globálne premenné. Autor toto nazýva lexikálny scope, pretože sa definuje v čase lexikálnej analýzy JavaScriptu, keď sa spúšťa v prehliadači.
Closure je už trochu zaujímavejší. Kdesi som čítal celkom akademickú poučku: „Closure je schopnosť objektu niesť si so sebou kontext, v ktorom vznikol.“ Páči sa mi, lebo znie tak múdro, ale po jej prečítaní oveľa múdrejší človek neostane. Takže inak. Pred chvíľou som písal, že JavaScript používa lexikálny scope, kde prístup k premennej je definovaný v čase lexikálnej analýzy. To isté sa deje aj pri iných jazykoch, ktoré som spomínal vyššie. Tak kde je potom rozdiel? Rozdiel je v tom, že funkcie sú v JavaScripte tzv. first-class citizen. To je zase iné, pekné pomenovanie preto, že s funkciou môžete pracovať ako s nejakým referenčným typom (napr. objetkom) a môžete ju preposielať z jednej časti kódu do druhej. Keď si ale predstavíte, že funkciu zadefinovanú v jednej časti kódu prepošlete do inej a tam ju spustite, k akým premenným bude mať prístup? Ak sa teraz pozriete na tú poučku vyššie, tak vás možno odpoveď napadne. Stále bude mať prístup k premenným, ktoré sa nachádzajú v mieste jej definície, nie vykonania. A to aj v prípade, že bola súčasťou nejakého objektu, ktorý sa už nepoužíva. Kým existuje niekde odkaz na metódu objektu, tak objekt so všetkými jeho premennými je v pamäti k dispozícii aspoň pre túto funkciu. Znamená to teda, že JavaScrip pri vyhodnocovaní stále používa lexikálny scope, aj keď došlo k presunu metódy do iného prostredia
To je tak v rýchlosti zrekapitulované, čo je Scope a čo Closure. V knihe toho nájdete omnoho viac aj s rôznymi špeciálnymi prípadmi, ktoré tieto základné pravidlá obchádzajú. Kniha je napísaná dobre v tom ohľade, že do tejto celkom kopmplikovanej témy sa ponára len veľmi pomaly. Neľutujem, že som ju čítal a už sa obhliadam po ďalších z edície „You dont know JS“.