Životní cyklus proměnné v Javascriptu

AndreaAndrea

Když vytváříte proměnnou a na jeden řádek napíšete kód jako je tento:

var greeting = 'Hello, world!'

Kolik operací si myslíte, že javascriptový engine provádí? Jednu, dvě nebo více? Správně je dvě: 1. deklaraci a 2. inicializaci.

1. Deklarace

Deklarací myslíme fázi, kdy je proměnná poprvé zaevidována v programu a současně je pro ni v paměti počítače vytvořeno místo. Konkrétně Javascript má pro tento účel strukturu, která se nazývá jmenný prostor, kde je pak proměnná dohledatelná pod určitým identifikátorem (jménem).

Deklarace může být provedena několika způsoby. Nejlepším způsobem je, když před název proměnné napíšeme jedno z klíčových slov var, let nebo const. Každý způsob má své vlastní chování a ovlivňuje scope (rozsah) a hosting (předčasné zvednutí) proměnné.

Deklarace var

Proměnné var mají funkční scope, což znamená, že jsou viditelné uvnitř funkce, ve které jsou deklarovány, a jsou hoistované (jsou zvednuty na začátek jejich scope).

Klíčová slova const a let

Tyto deklarace mají blokový scope, což znamená, že jsou viditelné pouze uvnitř bloku (složené závorky ), ve kterém jsou deklarovány. Na rozdíl od var, který je hoistován jsou const a let inicializovány až když k nim příjde řada v kódu, takže pokud se k nim pokusíte přistoupit dříve, dostanete ReferenceError.

Deklarace bez klíčového slova

Pokud napíšete deklaraci jako tato a = 1; nastane jedna ze dvou situací:

  1. vyhodí se chyba ReferenceError nebo nastane neočekávaný výsledek (ve struktním režimu).

  2. bude proměnná automaticky přidána do globálního objektu (window v prohlížeči, global v Node.js) a bude viditelná v celém kódu. Ani jedna situace není ideální. Vždy používejte při deklaraci klíčové slova i když vám kód funguje bez nich!

Nedeklarováný stav

Proměnné jsou deklarované, nebo nedeklarované (undeclared). Nedeklarováno tedy znamená, že proměná nebyla vytvořena. Javascript v tomto případě skončí s vyhozenou chybovou vyjímkou ReferenceError.

// ReferenceError: vyvojar is not defined
console.log(vyvojar) 

Datové typy

V mnoha jiných programovacích jazycích je součástí deklarace místo klíčového slova uveden datový typ proměnné. Javascript je dynamicky typovaný a určí si datový typ sám v závislosti na přiřazené hodnotě.

Pro začátečníky je absence datových typů usnadnění, nicméně časem můžeme narazit na některé problémy, jako je třeba časté přetypování proměnné nebo chyby, které se objeví až v průběhu času, kdy použijeme proměnnou v nevhodné operaci. V některých případech může být použití pevně typovaného jazyka výhodnější, protože vás upozorní na chyby předem při kompilaci a ne až při spuštění aplikace.

Javascript vás může překvapit ještě mechanismem, kterému se říká hoisting. Tem nám umožňuje deklarovat proměnné (a funkce) před jejich použitím.

2. Inicializace

Toto je bod, kdy je proměnné poprvé přiřazena hodnota po její deklaraci. Proměnné je přiřazena konkrétní hodnota pomocí operátoru přirazení (=).

Můžeme jí přiřadit libovolnou hodnotu, pokud to však neuděláme, pak se automaticky nastaví na hodnotu undefined (nedefinováno). Pozor! Není to stejný stav jako undeclared, ačkoliv to zní jako synonyma! Rozdíl mezi undefined a undeclared je, že nedefinovaná proměnná je již vytvořena a existuje, ale zatím jí nebyla přiřazena jiná hodnota. Zatím co nedeklarovaná proměnná neexistuje.

Proměnné deklarované pomocí const nelze změnit po její inicializaci.

const creature = 'dog';

3. Přiřazení (reasignace)

Přiřazení hodnoty proměnné se děje obvykle po její deklaraci.

V této operaci máme dvě strany, kterým se říká

  • cílový objekt nebo proměnná tzv. "target reference", do kterého se kopírují data nebo na kterou se odkazuje.
  • source reference cožjsou objekt nebo proměnná, ze kterého se data kopírují

Na tyto termíny narazíte hlavně při debugování, kde se objevují v chybových hláškách a snaží se vám napovědět, na které straně v přiřazení děláte chybu.

name = 'Amálka';
let age = 2;

console.log(name); // "Amálka"
console.log(creature); // "dog"
console.log(age); // 2

4. Zánik proměnné

Když je proměnná mimo dosah a není používána, garbage collector ji automaticky odstraní, aby uvolnil paměť.

Když nám už vytvořená proměnná není k užitku, můžeme ji zase zrušit a uvolnit ji z paměti. To se obvykle děje automaticky nebo při ukončení programu.