V původních verzích JavaScriptu se proměnná deklarovala pouze pomocí klíčového slova var
.
To, že se ve verzi ES 2015 zavedly další způsoby deklarování pomocí klíčových slov let
a const
mělo důvod.
Bez ohledu na to, jestli jste začínající nebo zkušenější programátor, který se s let
nebo const
zatím nesetkal, je důležité nejdřív pochopit koncept proměnného prostředí.
Hoisting
Proměnná deklarovaná slovem var
je skutečně přístupná před její deklarací díky procesu "hoistingu". Pokud se pokusíte přistoupit k takové proměnné, nevyvolá se chyba ReferenceError
, jak byste mohli očekávat (např. z chování jiných jazyků), ale vrátí se hodnota undefined
.
console.log(myVar); // undefined
var myVar = 21;
console.log(myVar); // 21
Toto chování může být matoucí, což je jeden z důvodů, proč se doporučuje používat let
a const
v novějších verzích JavaScriptu. Tyto proměnné jsou také vystaveny hoistingu, ale pokud se k nim pokusíte přistoupit před jejich deklarací, vyvolá se chyba ReferenceError
, což může být při ladění kódu užitečnější.
Použítí var v blocích (cyklu)
Podíváme na rozdíly v používání mezi var
a let
v cyklech.
Představme si scénář, kdy vytváříte pole funkcí v cyklu a každá funkce by měla vypsat číselnou hodnotu odpovídající její pozici (indexu) v poli.
- Vytvoříme pole s názvem
funkce
.
var funkce = [];
Protože si chceme ušetřit práci s vytvářením mnoha funkcí využijeme cyklu, pomocí kterého je vytvoříme naráz:
for (var i = 0; i < 3; i++) {
// uložíme si jednotlivé funkce do proměnné
funkce[i] = function() {
// každý z nich by měl zaznamenat svou hodnotu.
console.log("Hodnota: " + i);
};
}
Vidíte už problém? Pokud ne, můžeme si zkusit tyto funkce spustit, abychom viděli jak si pamatují proměnnou i
.
for (var j = 0; j < 3; j++) {
funkce[j]();
}
Pokud použijete var
pro deklaraci indexu cyklu, můžete narazit na neočekávané chování - každá funkce vypíše stejnou hodnotu, a tou je poslední hodnota indexu po doběhnutí cyklu.
Příčinou je, že všechny funkce odkazují na tu stejnou proměnnou i
a protože jsou volány později, proměnná i
bude mít hodnotu 3.
Pouhé deklarování i
místo jako let
by pomohlo předejít problému.
Viditelnost
Klíčové slovo var
je viditelné ve funkčním scope, takže proměnná i
je sdílena mezi všemi iteracemi cyklu.
Naproti tomu let
a const
způsobí omezení platnosti proměnných na úrovni blokového scope.
V tomto příkladu deklarujeme i
pomocí let
v cyklu:
for (let i = 0; i < 5; i++) {
console.log(i); // vypíše 0, 1, 2, 3, 4
}
console.log(i); // vyvolá chybu ReferenceError
Pokud se pokusíte přistoupit k proměnné y
nebo i
zvenčí cyklu, vyvolá se chyba ReferenceError
.
Rozšíření JS o blokový scope poskytlo programátorům lepší kontrolu nad používáním proměnných v našich programech.
To pomáhá zabránit konfliktům se stejnými jmény... Zrovna v cyklech a jednoduchých konstrukcích, totiž často recyklujeme jednopísmenkové proměnné.