Rekurzivní proměnné v JavaScriptu

Následující příspěvek v sobě v podstatě nenese nic důležitého, ale určitě zajímavého. Většina kódu je platformě závislých buď na webovém prohlížeči, na ostatních platformách je to obvykle podobné.

JavaScript je jazyk, kde v proměnné krom hodnoty nemusí být nic, případně tam může být všechno.

Např. kód:

var a = null;

Vytvoří proměnnou a, ve které nic není. Kód:

var b = "hello world";

Vytvoří proměnnou, ve které je stringová hodnota. Jak, ale do proměnné uložit vše? No docela jednoduše do proměnné můžete uložit obsah jiné proměnné. Např:

var c = b; // Uloží do proměnné c hodnotu z proměnné b.

No a tak stejně můžeme do proměnné uložit tzv. globální proměnnou. V prohlížeči je to prostě window, v node.js je to global.

var d = window;

Tato proměnná má tu vlastnost, že pokud je v ni „vše“, tak je tam určitě i proměnná d. Tedy následující výraz jednoznačně vrátí „vše“.

d.d

Pokud tento výraz vrací „vše“, tak je tam určitě i proměnná d. Následující výraz tedy vrací „vše“.

d.d.d

… o 10 d později …

d.d.d.d.d.d.d.d.d.d.d.d.d

předchozí výraz taktéž vrátí „vše“. Jestliže vrátil „vše“, tak tam určitě je proměnná b. Následující výraz tedy vrátí stringovou hodnotu „hello world“

d.d.d.d.d.d.d.d.d.d.d.d.d.b

Tohoto efektu lze ve skutečnosti docílit i bez globální proměnné.

var pole = [];
pole.push("Hi misaz");
pole.push(pole);
var vystup = pole[1][1][1][1][1][1][1][1][1][1][0];

Po provedení se v proměnné vystup objeví hodnota „Hi misaz“. Existuje však ještě jeden příklad, který využívá faktu, že každý objekt má konstruktor, včetně konstruktoru (funkce). Vytvořme si objekt

var e = {
       jmeno: "Hana"
}

Výraz:

e.constructor

vrátí konstruktor daného objektu, takže Object. Vrácená hodnota (funkce Object) má také konstruktor

e.constructor.constructor

vrátí Function, protože Object je funkce. A Funkce mají taky konstruktor, je jim funkce a tato funkce má také konstruktor….

e.constructor.constructor.constructor.constructor.constructor.constructor.constructor

vrátí Function.

Obdobný příklad je s funkcí, která vrátí sama sebe.

function f() {
       return f;
}

Pak výraz:

f()()()()()()()()();

Vrátí funkci f.

Rekurzi lze samozřejmě udělat i nepřímo. Např. že do každého objektu stringu (přes prototype) vložíme do nějaké vlastnosti hodnotu typu Number a typ Number rozšíříme o vlastnost s Stringovou hodnotu, pak je můžeme za sebou do nekonečna volat.

String.prototype.foo = 5;
Number.prototype.bar = "a";
"Hi misaz".foo.bar.foo.bar.foo.bar.foo.bar.foo

Možná by se takových příkladů dalo najít víc. Některých lze docílit i v jiných jazycích, v JavaScriptu je to však obzvlášť jednoduché.