functie die zichzelf herhaalt?

Status
Niet open voor verdere reacties.

Robdeprop

Gebruiker
Lid geworden
12 sep 2009
Berichten
27
Ik heb een vraag over javascript:

Is er een mogelijkheid dat bijv. functie hallo zichzelf kan heralen? Dus dan bedoel ik:

function hallo()
{
//doe wat dingen
**herhaal hallo()**
}

ik heb dit geprobeerd door simpelweg hallo() te doen, maar dit geeft nogal problemen...

Is er een andere manier?
 
Zoiets heet recursie: het aanroepen van 'jezelf'. Het gaat inderdaad zo:[JS]fuction stuff()
{
// do stuff

stuff(); // recursive call
}

// call it once
stuff();[/JS]Dit werkt goed, hoor, alleen je krijgt in je browser waarschijnlijk een 'too much recursion' error oid. Dit komt omdat je wel leuk dingen kan herhalen, maar als er geen stop op zit, eet het steeds meer CPU; hij moet alles namelijk 'instant' doen, en na een x aantal keer gaat het gewoon tijd kosten.

Mocht je gewoon om de zoveel tijd iets willen doen, kijk dan naar setInterval() en setTimeout().
 
aha...

Ik heb eens verder gezocht, en het blijkt een stack overflow te zijn (te veel recursive calls).

Dit is vervelend aangezien mijn script zo niet meer werkt... :confused:

Ik weet niet hoe ik mijn script simpeler kan maken...

Kan iemand mij daar bij helpen? (oja, dit script werkt niet in firefox, ik weet wel dat hij in IE8 werkt... Maar wel met stack overflow dus)

Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">



<html>
    <head>
        <title>Home4DSi - DSi quiz</title>
        <style>
          body { margin: 0px; }
          #topscreen, #bottomscreen { width: 240px; height: 176px; overflow: hidden;}

</style>

<script>

vr0=0;
vr1=0;
vr2=0;
vr3=0;
vr4=0;
vr5=0;
vr6=0;
vr7=0;
vr8=0;
vr9=0;

goed = 0
totaal = 0
aantalgoed = 0
begonnen = 0
nietmeerspelen = 0


function uitgespeeld()
{
	goed = 0
	resultaat = "Your score is " + aantalgoed + " out of 10!"
	vraag.Input.value = resultaat
	knopa.value = "Play again!";
	knopb.value = "Info";
	knopc.value = "Back to menu";
	knopd.value = "Back to Home4dsi";
	begonnen = 0
	goed=0
	aantalgoed = 0
	totaal = 0
	vr0=0;
	vr1=0;
	vr2=0;
	vr3=0;
	vr4=0;
	vr5=0;
	vr6=0;
	vr7=0;
	vr8=0;
	vr9=0;
	nietmeerspelen = 1
}



function volgendevraaga()
{
if(goed == 1)
{
juist = 'Correct! The right answer is: ' + antwoord
alert(juist)
aantalgoed = aantalgoed + 1
}
if(goed == 0)
{
	if (begonnen == 0)
		{
		totaal = totaal - 1
		}
		
}
if (goed != 0 && goed != 1)
{
onjuist = 'Wrong. The right answer should be: ' + antwoord
alert(onjuist)
}
if ( totaal == 10 )
{
alert("You answered 10 questions! That means you are done!")
uitgespeeld()
}
if (totaal != 10)
{
totaal = totaal + 1
quiz();
}
}

function volgendevraagb()
{
if(goed == 2)
{
juist = 'Correct! The right answer is: ' + antwoord
alert(juist)
aantalgoed = aantalgoed + 1
}
if(goed == 0)
{
	if (begonnen == 0)
		{
		totaal = totaal - 1
		}
}
if (goed != 0 && goed != 2)
{
onjuist = 'Wrong. The right answer should be: ' + antwoord
alert(onjuist)
}
if ( totaal == 10 )
{
alert("You answered 10 questions! That means you are done!")
uitgespeeld()
}
if (totaal != 10)
{
totaal = totaal + 1
quiz();
}
}




function volgendevraagc()
{
if(goed == 3)
{
juist = 'Correct! The right answer is: ' + antwoord
alert(juist)
aantalgoed = aantalgoed + 1
}
if(goed == 0)
{
	totaal = totaal - 1
}
if (goed != 0 && goed != 3)
{
onjuist = 'Wrong. The right answer should be: ' + antwoord
alert(onjuist)
}
if ( totaal == 10 )
{
alert("You answered 10 questions! That means you are done!")
uitgespeeld()
}
if (totaal != 10)
{
totaal = totaal + 1
quiz();
}
}

function volgendevraagd()
{
if(goed == 4)
{
juist = 'Correct! The right answer is: ' + antwoord
alert(juist)
aantalgoed = aantalgoed + 1
}
if(goed == 0)
{
	if (begonnen == 0)
		{
		totaal = totaal - 1
		}
}
if (goed != 0 && goed != 4)
{
onjuist = 'Wrong. The right answer should be: ' + antwoord
alert(onjuist)
}
if ( totaal == 10 )
{
alert("You answered 10 questions! That means you are done!")
uitgespeeld()
}
if (totaal != 10)
{
totaal = totaal + 1
quiz();
}
}


function quiz() 
{
vraagnummer=Math.floor(Math.random()*3);
if (nietmeerspelen == 0)
{
if (vraagnummer == 0)
	{
	if (vr0 == 1)
		{
		quiz()
		}
	if (vr0 == 0)
		{
		goed = 3
		antwoord = "A Nintendo fan"
		vraag.Input.value = "Who made Home4DSi?"
		knopa.value = "A: Nintendo";
		knopb.value = "B: Ubisoft";
		knopc.value = "C: A nintendo fan";
		knopd.value = "D: A group of students";
		vr0=1;
		}
	}
if (vraagnummer == 1)
	{
	if (vr1 == 1)
		{
		quiz()
		}
	if (vr1 == 0)
		{
		goed = 4
		antwoord = "Flipnote Studio"
		vraag.Input.value = "Where can you draw animations?"
		knopa.value = "A: Download play";
		knopb.value = "B: Flipnote Hatena";
		knopc.value = "C: Dsi Browser";
		knopd.value = "D: Flipnote Studio";
		vr1=1;
		}
	}
if (vraagnummer == 2)
	{
	if (vr2 == 1)
		{
		quiz()
		}
	if (vr2 == 0)
		{
		goed = 3
		antwoord = "Friends and Facebook"
		vraag.Input.value = "You can send taken pictures to?"
		knopa.value = "A: Nobody";
		knopb.value = "B: Friends";
		knopc.value = "C: Friends and Facebook";
		knopd.value = "D: Friends and Flipnote Hatena";
		vr2=1
		}
	}
if (vraagnummer == 3)
	{
	if (vr3 == 1)
		{
		quiz()
		}
	if (vr3 == 0)
		{
		goed = 4
		antwoord = "Draw with colours"
		vraag.Input.value = "What is new in pictochat?"
		knopa.value = "A: Send pictures";
		knopb.value = "B: Voice chat";
		knopc.value = "C: Private chat";
		knopd.value = "D: Draw with colours";
		vr3=1
		}
	}
if (vraagnummer == 4)
	{
	if (vr4 == 1)
		{
		quiz()
		}
	if (vr4 == 0)
		{
		goed = 3
		antwoord = "0.3 and 3.0"
		vraag.Input.value = "The DSi's cameras resolutions are?"
		knopa.value = "A: Both 0.3";
		knopb.value = "B: 0.3 and 1.3";
		knopc.value = "C: 0.3 and 3.0";
		knopd.value = "D: Both 3.0";
		vr4=1
		}
	}
if (vraagnummer == 5)
	{
	if (vr5 == 1)
		{
		quiz()
		}
	if (vr5 == 0)
		{
		goed = 2
		antwoord = "Friends, and Facebook"
		vraag.Input.value = "How much DSiWares are free?"
		knopa.value = "A: 1";
		knopb.value = "B: 2";
		knopc.value = "C: 3";
		knopd.value = "D: 4";
		vr5=1
		}
	}
if (vraagnummer == 5)
	{
	if (vr5 == 1)
		{
		quiz()
		}
	if (vr5 == 0)
		{
		goed = 1
		antwoord = "Yes, Bomberman Blitz"
		vraag.Input.value = "Is Bomberman available as DSiWare?"
		knopa.value = "A: Yes, Bomberman Blitz";
		knopb.value = "B: Yes, Bomberman Classic";
		knopc.value = "C: Yes, Bomberman Hero";
		knopd.value = "D: No";
		vr5=1
		}
	}
if (vraagnummer == 6)
	{
	if (vr6 == 1)
		{
		quiz()
		}
	if (vr6 == 0)
		{
		goed = 4
		antwoord = "All of the above"
		vraag.Input.value = 'What does the "i" in DSi mean?'
		knopa.value = "A: Eye (camera)";
		knopb.value = "B: Me (my own DSi)";
		knopc.value = "C: It resembles a human";
		knopd.value = "D: All of the above";
		vr6=1
		}
	}
if (vraagnummer == 7)
	{
	if (vr7 == 1)
		{
		quiz()
		}
	if (vr7 == 0)
		{
		goed = 2
		antwoord = "Friends, and Facebook"
		vraag.Input.value = "Does the DSi XL have better screens?"
		knopa.value = "A: Yes, also bigger";
		knopb.value = "B: No, only bigger";
		knopc.value = "C: No, only smaller";
		knopd.value = "D: Yes, also smaller";
		vr7=1
		}
	}
if (vraagnummer == 8)
	{
	if (vr8 == 1)
		{
		quiz()
		}
	if (vr8 == 0)
		{
		goed = 1
		antwoord = "No"
		vraag.Input.value = "Does the DSi support flash?"
		knopa.value = "A: No";
		knopb.value = "B: Some flash-objects";
		knopc.value = "C: Yes";
		knopd.value = "D: If you download it";
		vr8=1
		}
	}

if (vraagnummer == 9)
	{
	if (vr9 == 1)
		{
		quiz()
		}
	if (vr9 == 0)
		{
goed = 2
		antwoord = "Friends, and Facebook"
		vraag.Input.value = "Can a DSi play GBA games?"
		knopa.value = "A: Yes";
		knopb.value = "B: No";
		knopc.value = "C: A few";
		knopd.value = "D: Almost all";
		vr9=1
		}
	}
}
if (nietmeerspelen == 1)
{
nietmeerspelen = 0
}
}





</script>
       
    </head>
    <body>


        <div id="topscreen">
            <img id="title" src="images/dsiquizlogo.png">

        </div>
        <div id="bottomscreen"> 

<font size=2><center>
<p><form name="vraag"><input type='text' name='Input' value = 'Welcome to DSiquiz!' size = '35'></form></p>

<div><input type='button' name='knopa' value = 'Play!' oNclick="volgendevraaga()" size = '30'></font></div>
<div><input type='button' name='knopb' value = 'Info' oNclick="volgendevraagb()" size = '30'></font></div>
<div><input type='button' name='knopc' value = 'Back to menu' oNclick="volgendevraagc()" size = '30'></font></div>
<div><input type='button' name='knopd' value = 'Back to Home4dsi' oNclick="volgendevraagd()" size = '30'></font></div>
</center></font>


</div>

    </body>
</html>
 
Oef! Niet vervelend bedoelt, maar wat een vreselijk script. Toevallig nieuw in Javascript? :D:thumb:



Goed, hier wat ideeen:[JS]// een variabele maak je door ervoor het woordje 'var' te zetten:

var mijnVariabele;

// direct een waarde eraan vastmaken:

var mijnWaarde = "een string";[/JS][JS]// in plaats van 10x een variabele te hebben, kan je beter 1 array maken.
// dit is in principe gewoon een lijst van variabelen. Bijvoorbeeld:

var mijnArray = ['waarde1', 'waarde2', 'waarde3', 'nog iets', 42, 'zomaar een getal!', 1337];[/JS][JS]// functies kunnen zgn. parameters meekrijgen. Het mooie is dat je dan niet
// 20x dezelfde functie hoeft te maken, maar 1 functie met 1 parameter:

function test(data)
{
alert(data);
}

test(42); // alert met 42
test('hallo daar!'); // alert met 'hallo daar!'[/JS][JS]// Grote if-dingen kunnen meestal beter met een switch():

var waarde = 3;

switch(waarde)
{
case 3:
//doe iets als waarde 3 is;
break;
case 5:
// doe iets als waarde 5 is...
break;

// etcetera
}[/JS]ohja, en achter elke regel (behalve blocks en statements) hoort een punt-komma ( ; ). Je kan het in principe weglaten, maar dat's niet echt netjes.


Je recursie-fout komt denk ik omdat je in de quiz() functie dit doet:[js] // knip

function quiz()
{
vraagnummer=Math.floor(Math.random()*3);
if (nietmeerspelen == 0)
{
if (vraagnummer == 0)
{
if (vr0 == 1)
{
quiz() /* <--- kijk, recursie! */

// einde knip[/js]dit is de enige recursie die ik kon vinden; als je anders eens een alert('test!') in je quiz() bovenaan stopt; kijk dan eens of je veel alerts krijgt.



:thumb:
 
Laatst bewerkt:
ja, ik ben niet de beste in javascript... Maar de bedoeling was dus:

het is een quiz, en ik had een aantal vragen gemaakt. Ik wou dat de vragen geschud waren, dus ik deed dit:

Code:
function quiz() 
{
vraagnummer=Math.floor(Math.random()*3); // kiest de vraag
if (vraagnummer == 0)
    {
if (vr0 == 1)
        {
        quiz() // als vraag 1 al is geweest, moet hij een andere vraag kiezen
         }
if(vr0 == 0)
        {
        // hier worden dingen voor de vraag gedaan
        }

alleen als er al 2 vragen geweest zijn, gebeurt het wel eens dat hij bijvoorbeeld een aantal keer vraag 0 kiest en dan doet hij zo veel recursive calls dat hij een stack overflow weergeeft... Weet je misschien een andere manier waarop elke keer een andere vraag wordt gekozen?
 
Als je nou eens bijhoud welke vragen er zijn geweest; zoiets:[JS]var vragenGeweest = [false, false, ..., false];

//als een vraag klaar is: (var 'x' heft het vraag #)
vragenGeweest[x] = true;

//nieuwe vraag zoeken:
function quiz()
{
var random = Math.ceil(Math.random()*10);
if(vragenGeweest[random] === true)
{
// vraag is al geweest!
quiz();
return; // zorgt dat de functie 'stopt'
}

// ...[/JS]


:thumb:
 
Dankje, maar het probleem is dat als het script bijvoorbeeld per ongeluk 5 keer achter elkaar hetzelfde nummer kiest, hij te veel resurrective calls doet, en dus het script stopt. Is er een manier om dat te omzeilen?
 
Je kan in plaats van recursie gebruik maken van do...while:
[js]do
{
var random = Math.ceil(Math.random()*10);
} while (vragenGeweest[random] == true);[/js]
 
Bedankt voor alle reacties, mijn probleem is nu opgelost, alleen heb ik nu een ander probleem :o

Kan het dat je op een bepaalde plek "hallo" kan schrijven, en als er op een knop wordt geklikt, "hallo" wordt vervangen door "doei"?
 
Ja dat kan.
HTML:
<html>
<head>
<script type="text/javascript">
<!--
function veranderTekst(id, nieuwe_tekst)
{
        document.getElementById(id).innerHTML = nieuwe_tekst;
}
//-->
</script>
</head>
<body>
<span id="tekst">hallo</span>
<input type="button" value="Verander tekst" onClick="veranderTekst('tekst', 'doei')">
</body>
</html>
 
Status
Niet open voor verdere reacties.

Nieuwste berichten

Terug
Bovenaan Onderaan