Autor | Zpráva | ||
---|---|---|---|
Timy Profil |
#1 · Zasláno: 8. 2. 2009, 15:38:38
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 |
#2 · Zasláno: 8. 2. 2009, 16:32:54 · Upravil/a: ah01
„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 |
#3 · Zasláno: 8. 2. 2009, 16:38:48 · Upravil/a: Timy
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. |
||
Časová prodleva: 4 dny
|
|||
_es Profil |
#4 · Zasláno: 12. 2. 2009, 17:18:52 · Upravil/a: _es
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;} } } |
||
Časová prodleva: 15 let
|
0