Parameter an Funktion in Funktion übergeben
Matze
- javascript
Hallo an alle!
Ich versuche einer Funktion in einer anderen Funktion eine Variable zu übergeben aber irgendwie will mir das nicht gelingen.
Folgender Code sollte mir im Sekundentakt von 1 an nach oben zählen.
Dachte ich zumindest.
<script type="text/javascript">
function test(foo){
document.getElementById('bla').innerHTML = foo;
foo++;
var loop = setInterval(test(foo), 1000);
}
</script>
<body onload="test(1)">
<div id="bla"></div>
Die Fehlerkonsole sagt "too much recursion" und im div steht 3000.
Schreibe ich var loop = setInterval('test(foo)', 1000);
zeigt mir die Fehlerkonsole jede Sekunde "foo is not defined" und im div bleibt 1 stehn.
Was mache ich falsch? Ist das was ich will überhaupt möglich oder denk ich wieder in die falsche Richtung?
Danke und Grüße, Matze
Nur mal interessehalber: Kann es sein, dass Du setInterval und setTimeout verwechselst?
Gruß, LX
Folgender Code sollte mir im Sekundentakt von 1 an nach oben zählen.
Dachte ich zumindest.
falsch gedacht ;-)
<script type="text/javascript">
function test(foo){
document.getElementById('bla').innerHTML = foo;
foo++;
var loop = setInterval(test(foo), 1000);
du rufst hier die Funktion test() auf, die dann wieder an die Stelle kommt und dann test() aufruft usw...
Ein Interval wird nie aufgerufen, da der Rückgabewert von test() undefiniert ist, er müßte aber eine Funktionsreferenz sein.
Deshalb:
Die Fehlerkonsole sagt "too much recursion" und im div steht 3000.
Du möchtest ein closure verwenden:
[code lang=javascript]var loop = window.setInterval(function() { test(foo);}, 1000);
Allerdings würde ich dass nicht empfehlen, da du dann jede Sekunde einen neuen Interval startest, der dann wieder jede Sekunde einen Interval startet usw.
Daher besser:
`var loop = window.setTimeout(function() { test(foo);}, 1000);`{:.language-javascript}
> Schreibe ich `var loop = setInterval('test(foo)', 1000);`{:.language-javascript} zeigt mir die Fehlerkonsole jede Sekunde "foo is not defined" und im div bleibt 1 stehn.
Weil dann die Funktion im Kontext von window ausgeführt wird und dort ist foo nicht definiert.
Struppi.
Hallo und guten Abend Struppi und auch LX!
du rufst hier die Funktion test() auf, die dann wieder an die Stelle kommt und dann test() aufruft usw...
Achso, stimmt. Quasi ein virtuelles Feedback.
Ein Interval wird nie aufgerufen, da der Rückgabewert von test() undefiniert ist, er müßte aber eine Funktionsreferenz sein.
Stimmt, weil die Funktion ja nie ein Ende findet.
Deshalb:
Die Fehlerkonsole sagt "too much recursion" und im div steht 3000.
Hm, die 3000 ist dann vermutlich der von Firefox bestimmte Wert wie oft er versucht die Funktion zu Ende zu bringen. Irgendwann hab ich ihn damit auch mal abstürtzen lassen ^^ So ganz ohne Fehler oder Fehlerberichtmöglichkeit... einfach zu - fertig.
Daher besser:
var loop = window.setTimeout(function() { test(foo);}, 1000);
Danke, ich bin leider nicht so fit in den JavaScript-Funktionen und ich finde bei SelfHtml werden viele Sachen in der Richtung nur leicht "angekratzt" oder man findet sie sehr schwer[1]. Das macht es manchmal schwer. Und Google ist auch nicht immer eine kompetente Lösung.
Schreibe ich
var loop = setInterval('test(foo)', 1000);
zeigt mir die Fehlerkonsole jede Sekunde "foo is not defined" und im div bleibt 1 stehn.Weil dann die Funktion im Kontext von window ausgeführt wird und dort ist foo nicht definiert.
Achso, also "eine Etage über" der Funktion? Oder hab ich das falsch verstanden?
Danke und Grüße, Matze
Hi,
Danke, ich bin leider nicht so fit in den JavaScript-Funktionen und ich finde bei SelfHtml werden viele Sachen in der Richtung nur leicht "angekratzt" oder man findet sie sehr schwer[1].
So wie deine Fussnoten.
Das macht es manchmal schwer. Und Google ist auch nicht immer eine kompetente Lösung.
Die Dokumentationen zu einzelnen Objekten und Eigenschaften/Methoden bspw. im Developer-Bereich von Mozilla sind idR. recht ausfuehrlich, und fuer IE-spezifisches ist die MSDN auch immer eine recht ergiebige Quelle.
Und zum Thema Grundlagen gibt's einen Haufen gute Tutorials, auch auf aktuellem Stand (objektorientierter Ansatz, unobstrusive, etc.)
MfG ChrisB
Hallo Chris!
... oder man findet sie sehr schwer[1].
So wie deine Fussnoten.
Es soll ja auch nicht zu einfach werden - du musst zwischen den Zeilen lesen ;)
Ich weiß auch nicht, sowas passiert mir heut schon den ganzen Tag, aber solange ich noch drüber lachen kann^^
[1] Bsp: Validator findet man unter de.selfhtml.org -> (gaaaanz unten im ersten Abschnitt) Kleine Helferlein -> Sonstiger -> SELFHTML-Validator für HTML / XHTML / WML / XML
Man könnte meinen, man wollte ihn verstecken damit... zu viele Gedanken die man da rein interpretieren könnte.
Die Dokumentationen zu einzelnen Objekten und Eigenschaften/Methoden bspw. im Developer-Bereich von Mozilla sind idR. recht ausfuehrlich, und fuer IE-spezifisches ist die MSDN auch immer eine recht ergiebige Quelle.
Und zum Thema Grundlagen gibt's einen Haufen gute Tutorials, auch auf aktuellem Stand (objektorientierter Ansatz, unobstrusive, etc.)
Mein Problem ist, dass die meißten ausführlichen Beschreibungen auf Englisch sind und ich es, mit meinem nicht Fachenglisch, sehr schwer und missverständlich finde. Habe ich aber schon öfter erwähnt.
Grüße, Matze
Ein Interval wird nie aufgerufen, da der Rückgabewert von test() undefiniert ist, er müßte aber eine Funktionsreferenz sein.
Stimmt, weil die Funktion ja nie ein Ende findet.
Nein, es gibt einfach kein Interval der ausgfeührt werden kann, da test() undefined zurückliefert.
Deshalb:
Die Fehlerkonsole sagt "too much recursion" und im div steht 3000.
Hm, die 3000 ist dann vermutlich der von Firefox bestimmte Wert wie oft er versucht die Funktion zu Ende zu bringen.
Wie tief die Rekursion geht, ja.
Daher besser:
var loop = window.setTimeout(function() { test(foo);}, 1000);
Danke, ich bin leider nicht so fit in den JavaScript-Funktionen und ich finde bei SelfHtml werden viele Sachen in der Richtung nur leicht "angekratzt" oder man findet sie sehr schwer[1]. Das macht es manchmal schwer. Und Google ist auch nicht immer eine kompetente Lösung.
Funktionsreferenzen, closures oder anonyme Funktionen sind auch nicht unbedingt Themen die in eine Doku müssen, die auch für Einsteiger gedacht ist. Dafür gibt es aber z.b. diesen ausführlichen Artikel von Mathias.
Schreibe ich
var loop = setInterval('test(foo)', 1000);
zeigt mir die Fehlerkonsole jede Sekunde "foo is not defined" und im div bleibt 1 stehn.Weil dann die Funktion im Kontext von window ausgeführt wird und dort ist foo nicht definiert.
Achso, also "eine Etage über" der Funktion? Oder hab ich das falsch verstanden?
Ja, das kann man so sagen.
Struppi.
Hallo Struppi!
Stimmt, weil die Funktion ja nie ein Ende findet.
Nein, es gibt einfach kein Interval der ausgfeührt werden kann, da test() undefined zurückliefert.
Hab ich das nicht gesagt? Zumindest gemeint ;) Ich hab schon verstanden,
dass die Funktion sich selbst aufruft bevor ein Interval ausgeführt werden kann. Oder nicht?
Das test()nichts zurück liefert ist in dem Fall doch gar nicht mehr relevant oder? Würde es an der Endlosschleife etwas ändern wenn ich vor oder nach dem Interval ein return... setzen würde?
Setzte ich es davor ist die Funktion damit automatisch beendet oder?
Setze ich es dahinter wird return wegen der Endlosschleife nie aufgerufen.
Danke, ich bin leider nicht so fit in den JavaScript-Funktionen (...)
Funktionsreferenzen, closures oder anonyme Funktionen sind auch nicht unbedingt Themen die in eine Doku müssen, die auch für Einsteiger gedacht ist. Dafür gibt es aber z.b. diesen ausführlichen Artikel von Mathias.
Danke, werde ich lesen!
Grüße, Matze
Stimmt, weil die Funktion ja nie ein Ende findet.
Nein, es gibt einfach kein Interval der ausgfeührt werden kann, da test() undefined zurückliefert.
Hab ich das nicht gesagt? Zumindest gemeint ;) Ich hab schon verstanden,
dass die Funktion sich selbst aufruft bevor ein Interval ausgeführt werden kann. Oder nicht?
Das test()nichts zurück liefert ist in dem Fall doch gar nicht mehr relevant oder? Würde es an der Endlosschleife etwas ändern wenn ich vor oder nach dem Interval ein return... setzen würde?
Nein, in dem Fall hast du Recht und das ist auch das eigentliche Problem der Fehlermeldung, aber nicht das Problem deiner Schreibweise.
Du kannst z.b. sowas machen:
function test(){
var foo = 1;
window.setInterval( t_func(foo), 100);
}
function t_func(p) {
return function() {
p++;
window.status = p;
}
}
test();
In dem Fall gibt t_func() eine Funktion zurück und diese wird alle 100ms aufgerufen. In deinem Fall gibt die Funktion halt nichts zurück - was aber nichts an dem anderen Grundsätzlichen Denkfehler ändert.
Struppi.
function test(foo){
document.getElementById('bla').innerHTML = foo;
foo++;
var loop = setInterval(test(foo), 1000);
}
Ich tendiere hier mittlerweile ja zu Currying anstatt ständig neue Funktionen zu erzeugen:
Mit </archiv/2008/12/t180183/#m1190334>:
var loop = window.setTimeout(test.curry(foo), 1000);
Die Funktionsausdrücke sind nämlich Speicherfresser, weil sie eben als Closures wirken und den Scope der umgebenen Funktion bis in alle Ewigkeit erhalten. Der Garbage Collector kann davon auch nichts abräumen. Das ist bei einer Funktion natürlich egal, aber wenn man ständig unzählige Closures erstellt, wird es brenzlig. Auf dicken Rechner merkt man nicht unbedingt, wenn der Speicher volläuft, man hat ja heutzutage Gigabyteweise davon. Aber auf kleineren mobilen Zugangsgeräten merkt man speicherhungrige JavaScripte sehr schnell.
Beim Currying wird natürlich auch nichts anderes als eine Closure angelegt, aber diese schließt kontrolliert das Funktionsobjekt ein sowie einen Array mit den übergebenen Parametern. Das ist auch nicht so toll, weil die auf ewig bestehen bleiben, aber weiter optimieren lässt sich das glaube ich nicht.
Mathias