Rozdíl mezi null a undefined v JavaScriptu

Před pár dny mi dorazil mail od Jakuba Vrány, ve kterém se mě ptal, jestli nevím, proč má JavaScript kromě hodnoty null ještě undefined. Protože si myslím, že má odpověď by mohla zajímat více lidí, rozhodl jsem se ji spolu s původním dotazem zveřejnit a budu rád, pokud ji případně v komentářích doplníte.

Dotaz

Tušíš, proč je v JavaScriptu jak hodnota null, tak undefined? Podle mě by se všude na místě null dalo používat undefined. Má nějaký smysl mít dvě speciální hodnoty?

Odpověď

Nějaký "oficiální" důvod jsem nikde nenašel. Ve specifikaci je sice popsáno chování, ale zdůvodnění existence chybí.

Osobně se domnívám, že jde hlavně o sémantický rozdíl.

Hodnotu undefined vrací konstrukce jazyka, když chtějí říct "nevím":

V podstatě jsou to situace, kdy by jiné jazyky vrátily chybu. Kdyby se všechny situace, kdy se vrací undefined, nahradily vyvoláním chyby, JavaScript by dál fungoval a byl konzistentní, jen by byl o něco striktnější.

Hodnota undefined je tedy taková spíš systémová záležitost; prostředek, jak jazyk učinit volnější. Nemyslím, že by programátor měl vůbec kdy napsat výraz, který by undefined vracel.

Hodnota null je naopak hodnota, u které se využití uživatelem očekává – jazyk sám ji používá minimálně. Slouží především k tomu, aby uživatel měl jak vyjádřit "nezadáno".

Otázkou je, zda oddělení null a undefined nepřináší víc problémů než užitku. Pokud by se tyto hodnoty sloučily a všude, kde se dnes vrací undefined, by se vracelo null, mělo by za důsledek neodlišitelnost některých situací:

Na první pohled se zdá, že to jsou docela vážné problémy, ale zkušenost z jiných jazyků ukazuje, že zdaleka tak vážné nejsou. Například v jazyce Ruby mají nedefinované instanční proměnné hodnotu nil (ekvivalent null) a tuto hodnotu vrací také neúspěšný přístup k položce v hash tabulce nebo přístup k položce pole, co je out-of-range. Podobně vrací nil metoda bez explicitního return. Nezdá se, že by toto někomu vadilo (lidi na Ruby kritizují hodně věcí, ale tohle ne).

Toť asi vše, co jsem k tomuto tématu schopen říct.