klíčem k pochopení návrhových vzorů jako je ŽIVOT je uvědomit si, že před ES6, JavaScript pouze doporučené funkce rozsah (tedy chybí blok scope), předávání hodnot odkazem uvnitř uzávěry. To již není tento případ, protože ES6 verze JavaScriptu implementuje block scoping pomocí nových klíčových slov let
a const
.
Hodnocení contextEdit
nedostatek blok scope znamená, že proměnné definované uvnitř (například) pro smyčce bude mít své definice „vyvěšena“ na horní části obvodových funkcí. Vyhodnocení funkce, která závisí na proměnných modifikovaných vnější funkcí (včetně iterace), může být obtížné. Můžeme to vidět bez smyčky, pokud aktualizujeme hodnotu mezi definováním a vyvoláním funkce.
var v, getValue;v = 1;getValue = function () { return v; };v = 2;getValue(); // 2
Zatímco výsledek se může zdát zřejmé, když aktualizace v
ručně, to může produkovat nezamýšlené výsledky, když getValue()
je definována uvnitř smyčky.
dále funkce předá v
jako argument a je vyvolána okamžitě, při zachování kontextu provádění vnitřní funkce.
var v, getValue;v = 1;getValue = (function (x) { return function () { return x; };})(v);v = 2;getValue(); // 1
to odpovídá následujícímu kódu:
var v, getValue;v = 1;function f(x) { return function () { return x; };};getValue = f(v);v = 2;getValue(); // 1
efektivní JavaScript Davida Hermana obsahuje příklad ilustrující problémy kontextu hodnocení uvnitř smyček. Zatímco Hermanův příklad je záměrně spletitý, vychází přímo ze stejného nedostatku blokového rozsahu.
Založení soukromé proměnné a accessorsEdit
Životů jsou také užitečné pro stanovení soukromé metody pro dostupné funkce, zatímco ještě odhalení některých vlastností pro pozdější použití. Následující příklad pochází z Almanova příspěvku na IIFEs.
// "counter" is a function that returns an object with properties, which in this case are functions.var counter = (function () { var i = 0; return { get: function () { return i; }, set: function (val) { i = val; }, increment: function () { return ++i; } };})();// These calls access the function properties returned by "counter".counter.get(); // 0counter.set(3);counter.increment(); // 4counter.increment(); // 5
Pokud se pokusíme o přístup counter.i
z globálního prostředí, bude definováno, jako je uzavřený uvnitř vyvolána funkce a není vlastnost counter
. Podobně, pokud se pokusíme o přístup k i
, bude to mít za následek chybu, protože jsme v globálním prostředí nevyhlásili i
.