| 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: 17 let
|
|||
0