dp: Wert-Übergabe bei window.setTimeout()

Moin,

ich möchte über window.setTimout() eine Funktion aufrufen und dieser Funktion einen Parameter übergeben. Dies sollte laut SelfHTML über Zeichenkettenverknüpfung gehen.

window.setTimeout("animateAutoCompletion(" + object + ")",250);

Nur meldet mir die JavaScript-Konsole des Firefox einen Fehler. Missing "]" after Elementlist in Line wo das da oben steht ;-). Ich fürchte, dass das Objekt wegen der Zeichenkettenverknüpfung irgendwie hopps geht, wüsste aber nicht, wie ich es sonst elegant übertragen könnte - eine globale Variable mal ausgeschlossen...

Gruß
Daniel

  1. ich möchte über window.setTimout() eine Funktion aufrufen und dieser Funktion einen Parameter übergeben. Dies sollte laut SelfHTML über Zeichenkettenverknüpfung gehen.

    window.setTimeout("animateAutoCompletion(" + object + ")",250);

    ich gege mal davon aus object ist ein Object?
    Dann geht das so nicht, in dem Fall kannst du entweder mit einer anonymen Funktion arbeiten

    window.setTimeout( function() {animateAutoCompletion(object);},250);
    oder mit einer globalen Variabel.

    Struppi.

    --
    Javascript ist toll (Perl auch!)
    1. Neee, globale Variable ist mir zu unständlich bzw. sieht das zu sehr nach Gefrickel aus. Ich mach's jetzt über die anonyme Funktion. Vielen Dank!!!

      Gruß
      Daniel

    2. Hallo,

      Dann geht das so nicht, in dem Fall kannst du entweder mit einer anonymen Funktion arbeiten

      Zur Erläuterung: Vielleicht sollte man dazu sagen, dass nicht der springende Punkt ist, dass die Funktion »anonym« ist. Man könnte ihr ruhig einen Namen geben, das ist nicht erheblich.

      Das Stichwort lautet Closure. In der Funktion, die innerhalb einer anderen Funktion notiert wird, hat man Zugriff auf die lokalen Variablen der äußeren Funktion - auch wenn sie später außerhalb dieses Geltungsbereiches ausgeführt wird, wie es bei setTimeout der Fall ist.

      function äußere_funktion (parameter) {  
         var lokale_variable = parameter;  
         function innere_funktion () {  
            alert(lokale_variable);  
         }  
         window.setTimeout(innere_funktion, 1000);  
      }  
      äußere_funktion("Closure");
      

      Das illustriert den Closure-Effekt.

      Jetzt gibt es noch andere Arten, eine Funktion zu notieren als die übliche, oben gezeigte. Es gibt sogenannte Function-Expressions, die man an jeder beliebigen Stelle verwenden kann, wo Ausdrücke erlaubt sind. Sie geben ein Function-Objekt zurück (Funktionen sind in JavaScript selbst Objekte), dass man dann in einer Variable speichern kann oder einer Funktion als Parameter übergeben kann (wie im setTimeout-Beispiel):

      alert(function () { alert("Function-Expression"); })  
      var func = function () { alert("Function-Expression"); };  
      window.setTimeout(function () { alert("Function-Expression"); }, 1000);  
      (function (param) { alert(param); })("Function-Expression");
      

      Diese Funktionen sind »anonym«, weil sie nicht notwendigerweise unter einem Namen abgespeichert sind, sondern erst einmal nur solange existieren, bis der Ausdruck abgearbeitet ist.

      Wie alle Funktionen, die in anderen Funktionen notiert werden, wirken auch Function-Expressions als Closures.

      function äußere_funktion () {  
         var lokale_variable = "Closure";  
         // Speichere das zurückgegebene Funktionsobjekt im globalen Objekt innere_funktion:  
         innere_funktion = function () { alert(lokale_variable); };  
      }  
      äußere_funktion();  
      innere_funktion();
      

      Obwohl die äußere_funktion schon längst nicht mehr ausgeführt wird, wurden die lokalen Variablen, die beim Funktionsaufruf angelegt wurden, noch nicht aus dem Speicher gelöscht, denn innere_funktion (die in dem Fall global verfügbar gemacht wird) hat diese »eingeschlossen«.

      Mathias

      1. Dann geht das so nicht, in dem Fall kannst du entweder mit einer anonymen Funktion arbeiten

        Zur Erläuterung: Vielleicht sollte man dazu sagen, dass nicht der springende Punkt ist, dass die Funktion »anonym« ist. Man könnte ihr ruhig einen Namen geben, das ist nicht erheblich.

        Das Stichwort lautet Closure. In der Funktion, die innerhalb einer anderen Funktion notiert wird, hat man Zugriff auf die lokalen Variablen der äußeren Funktion - auch wenn sie später außerhalb dieses Geltungsbereiches ausgeführt wird, wie es bei setTimeout der Fall ist.

        Nur als Ergänzung, das funktioniert nicht im < IE 5.x und Netscape 4

        Obwohl die äußere_funktion schon längst nicht mehr ausgeführt wird, wurden die lokalen Variablen, die beim Funktionsaufruf angelegt wurden, noch nicht aus dem Speicher gelöscht, denn innere_funktion (die in dem Fall global verfügbar gemacht wird) hat diese »eingeschlossen«.

        Und hier ein Frage, es gibt ja diesen ewig langen Thread bei Quirksmode wegen addEvent (http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html), dort wird ja auch von Speicherlöchern im zusammenhang mit dem IE und closures (bzw. anonymen Funktionen) gesprochen. Ich bin dem ganzen nicht 100% nachgegangen, aber wenn ich das richtig verstanden habe (kann sein dass ich es nicht habe) hat der IE Probleme solche Variabeln wieder frei zu geben, oder trifft das nur unter manchen Umständen zu?

        Struppi.

        --
        Javascript ist toll (Perl auch!)
        1. Hallo,

          Und hier ein Frage, es gibt ja diesen ewig langen Thread bei Quirksmode wegen addEvent (http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html), dort wird ja auch von Speicherlöchern im zusammenhang mit dem IE und closures (bzw. anonymen Funktionen) gesprochen. Ich bin dem ganzen nicht 100% nachgegangen, aber wenn ich das richtig verstanden habe (kann sein dass ich es nicht habe) hat der IE Probleme solche Variabeln wieder frei zu geben, oder trifft das nur unter manchen Umständen zu?

          Es gibt wohl einige Szenarien (siehe meine Linksammlung, insbesondere den Microsoft-Artikel), aber besonders häufig sind Memory-Leaks aufgrund von kreisförmigen Referenzen im Zusammenhang mit Event-Handling.

          Memory Leaks treten wohl quasi immer auf, wenn man ein solches Schema hat:

          function func () {
             ...
             var element = document.getElementById("xyz");
             ...
             element.onevent = function () {}; // Closure, schließt »element« ein
             ...
          }

          Der DOM-Elementknoten in element hat eine Eigenschaft onevent mit einer Function, in deren Scope die Variable element »eingeschlossen« ist, welche wiederum auf den Elementknoten zeigt. Ein solcher zirkulärer Verweis führt zu Memory-Leaks. IE räumt diese beteiligten Objekte nicht ordnungsgemäß aus dem Speicher, deshalb muss man den Verweis von Hand beim onunload löschen. Dasselbe gilt bei der Verwendung von addEvent.

          Mathias

  2. Hallo,

    window.setTimeout("animateAutoCompletion(" + object + ")",250);

    Nur meldet mir die JavaScript-Konsole des Firefox einen Fehler. Missing "]" after Elementlist

    Ist dir auch klar, warum du auf diese Weise kein solches Objekt übergeben kannst? Wenn du es in einen String einbaust mit dem »+«-Operator, wird es selbst automatisch in einen String umgewandelt (d.h. dessen Methode toString() wird aufgerufen). Wenn es sich um einen Elementknoten handelt, dann kommt z.B. »[object HTMLDivElement]« heraus. Der JavaScript-Code sähe dann so aus:

    animateAutoCompletion([object HTMLDivElement])

    Das ist natürlich kein korrekter Code, sondern Unsinn. Solche Objekte lassen sich nicht in einen String umwandeln. Auf die Weise kann man nur Strings und Zahlenwerte übergeben.

    Mathias

    1. animateAutoCompletion([object HTMLDivElement])

      Das ist natürlich kein korrekter Code, sondern Unsinn. Solche Objekte lassen sich nicht in einen String umwandeln. Auf die Weise kann man nur Strings und Zahlenwerte übergeben.

      Auf diese Weise, nur Zahlen. Strings müssen ausserdem noch in Anführungszeichen gesetzt werden.

      Wobei du wahrscheinlich mit, "diese Weise", eher die Art der Übergabe der Funktion gemeint hast.

      Struppi.

      --
      Javascript ist toll (Perl auch!)