Autor Zpráva
Timy
Profil
Mám tyto dvě funkce:

<script>
// Cyklus
function cyklus(indexCyklu)
{
	for(; indexCyklu >= 0; indexCyklu--)
	{
		/* jakýkoliv ekvivalentní kod */
	}
}

// Rekurze
function rekurze(indexRekurze)
{
	if(indexRekurze >= 0)
	{
		/* jakýkoliv ekvivalentní kod */
		rekurze(indexRekurze - 1);
	}
}
</script>


Otázka zní, jestli při použití ekvivalentního kódu v těle funkcí (namísto komentáře) se vždy provede stejná akce nebo jestli se může výsledek nějak lišit. Příklad ekvivalentního kódu může být alert(indexCyklu) a alert(indexRekurze). Po zavolání funkcí se stejnými argumenty — cyklus(5) a rekruze (5) — by se stalo totéž. Existuje nějaký kód, který by po vykonání udělal něco jiného?

Měli jsme tento problém na zkoušce a nikdo na to nepřišel :-). Bylo to ale v jiném jazyku, takže si nejsem úplně jistý, jestli se to v Javscriptu bude chovat stejně, ale zkusil jsem ten problém nasimulovat jak nejlépe to šlo. Snad jsem nezapomněl na nějakou triviálnost, která by mi to celé zkazila :-). Je zapovězeno měnit iterační proměnnou nebo v těle rekurzivně volat tytéž funkce (ale ono by to stejně asi ani nemělo vliv).
ah01
Profil
Existuje nějaký kód, který by po vykonání udělal něco jiného?
Ano, existuje. Problém je v tom, že cyklus se celý provede v jednom scope (jak je to česky - context?), kdežto rekurze bude mít při každém průchodu scope jiný.

Jako příklad se nabízí události navázané na DOM. Řekněme že máme nějaké pole DOM elementů a budeme jim přiřazovat obsluhu onclick. Takže ten ekvivalentní kód by vypadal nějak takto:

list[index].onclick = function(){
    alert(index);
}


Vlivem closureu (lexikální uzávěry?) pak obsluhy událostí přiřazené v cyklu používají proměnnou indexCyklus, která po doběhnutí cyklu obsahuje -1. Kdežto obsluhy přiřazené v rekurzi používají proměnnou, která byla v dané iteraci.
V případě rekurze obdržíme po klikání na elementy jejich pořadová čísla. V případě iterace to bude vždy -1.

Ten příklad: http://jslab.net/pub/jpw/rekurze-vs-iterace.html

Otázkou ale je, jestli by to takto fungovalo i v tom jazyku, ze kterého jsi dělal zkoušku.
Timy
Profil
ah01
Tak jest, lexikální uzávěry. Hezky je to vidět taky na tomto příkladu:

var arr1 = new Array();
var arr2 = new Array();

// Cyklus
function cyklus(indexCyklu)
{
	for(; indexCyklu >= 0; indexCyklu--)
	{
		arr1[indexCyklu] = function id(){return indexCyklu;}
	}
}

// Rekurze
function rekurze(indexRekurze)
{
	if(indexRekurze >= 0)
	{
		arr2[indexRekurze] = function id(){return indexRekurze;}
		rekurze(indexRekurze - 1);
	}
}


Problém je v tom, že cyklus se celý provede v jednom scope (jak je to česky - context?)
My tomu říkáme prostředí.

V JS je to vlastně jednodušší, protože to s tím onclickem je hezký a zároveň častý příklad. My nic tomu podobného nedělali, jinak by si to taky někdo uvědomil.
_es
Profil
Timy
Pre zaujímavosť, funkcia cyklus sa dá jednoducho zmeniť tak, aby dávala rovnaké výsledky bez rekurzie:
function cyklus(indexCyklu)
{
    for(; indexCyklu >= 0; indexCyklu--)
    with({indexCyklu:indexCyklu}){
        arr1[indexCyklu] = function id(){return indexCyklu;}
    }
}

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: