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é.