Thomas: rekursiver Funktionsaufruf wird nicht zu Ende geführt!!!

Hallo liebe JS-Genmeinde,

ich versuche gerade ein Script für ein Baummenü zu schreiben und bin dabei auf ein Problem gestoßen was ich mir nicht erklären kann.

Ich erzeuge über eine Funktion 'Link()' ein Objekt und über eine Funktion 'addLink()' Instanzen dieses Objektes. Dabei kann als Parameter 'bolOrdner' übergeben werden, ob es sich um einen Ordner handelt. Daraufhin wird dem Link ein Array hinzugefügt, welches die Unterlinks aufnehmen soll.

Um das Menü darzustellen habe ich folgende Funktion 'erzeuge()' geschrieben. Diese soll sich, wenn ein Link das Atribut 'bolOrdner' erfüllt, selbst aufrufen um alle Unterelemente abzuarbeiten.

Dies funktioniert auch soweit. Jedoch findet die Rekursion nicht wieder zurück, wenn die tiefste Verschachtelungsebene des ersten Ordners erreicht ist. Das Menü wird nur bis dahin erzeugt und nicht weiter.

Was mache ich falsch???

function erzeuge()
  {
    elm = this.Elemente;
    for (x=0; x<elm.length; x++)
    {
      document.write(getLink(elm[x]));
      if (elm[x].bolOrdner)
      {
 document.write('<ul>');
        elm[x].erzeuge();
        document.write('</ul>');
      }
    }

}

Danke im Voraus für Eure Hilfe.

  1. Hallo Thomas

    elm = this.Elemente;

    var elm = this.Elemente;

    sonst ist es eine globale Variable

    for (x=0; x<elm.length; x++)

    for (var x=0; x<elm.length; x++)

    dito, kann aber sein, dass das implizit schon so ist.

    Gruss,
     Carsten

    1. Hallo Thomas

      elm = this.Elemente;

      var elm = this.Elemente;

      sonst ist es eine globale Variable

      Quatsch. Wenn elm in der Funktion definiert wird ist es lokal. Es sei denn, es gibt schon eine globale Variable dieses Namens. Das geht aber aus dem Code nicht hervor. Außerdem ist es irrelevant, weil elm ja sowieso bei jedem Funktionsaufruf neu besetzt wird.

      for (x=0; x<elm.length; x++)

      for (var x=0; x<elm.length; x++)

      dito, kann aber sein, dass das implizit schon so ist.

      siehe oben

      Gruss,
      Carsten

      1. Hallo Thomas

        elm = this.Elemente;

        var elm = this.Elemente;

        sonst ist es eine globale Variable

        Quatsch. Wenn elm in der Funktion definiert wird ist es lokal. Es sei denn, es gibt schon eine globale Variable dieses Namens. Das geht aber aus dem Code nicht hervor. Außerdem ist es irrelevant, weil elm ja sowieso bei jedem Funktionsaufruf neu besetzt wird.

        Sorry Emmi, aber da hat Carsten recht. Es funzt ja jetzt und weder die Variable 'elm' noch 'x' habe ich irgendwo anders im Quelltext schon mal verwendet.

        for (x=0; x<elm.length; x++)

        for (var x=0; x<elm.length; x++)

        dito, kann aber sein, dass das implizit schon so ist.

        siehe oben

        Gruss,
        Carsten

        1. » Sorry Emmi, aber da hat Carsten recht. Es funzt ja jetzt und weder die Variable 'elm' noch 'x' habe ich irgendwo anders im Quelltext schon mal verwendet.<<

          Hm, dann müßte zumindest auch SelfHTML an dieser Stelle korrigiert werden, wo steht, daß man das "var" genausogut weglassen kann:

          ZITAT:
          --------------------------------------------------------------------
           Variablen definieren
           Anzeigebeispiel: So sieht's aus

          Variablen sind Speicherbereiche, in denen Sie Daten, die Sie im Laufe Ihrer Programmprozeduren benötigen, speichern können. Der Inhalt, der in einer Variablen gespeichert ist, wird als "Wert" bezeichnet. Sie können den Wert einer Variablen jederzeit ändern. Um mit Variablen arbeiten zu können, müssen Sie die benötigten Variablen zuerst definieren.

          Beispiel:
          <html>
          <head>
          <title>Sinn des Lebens zum Quadrat</title>
          <script language="JavaScript">
          <!--
            var Hinweis = "Gleich werden Quadratzahlen ausgegeben";
            alert(Hinweis);

          function SchreibeQuadrate()
            {
                var SinnDesLebens = 42;
                var i, x;
                var Satzteil = "Das Quadrat von ";
                for(i=1; i <= SinnDesLebens; ++i)
                  {
                    x = i * i;
                    document.write(Satzteil + i + " ist " + x + "<br>");
                  }
            }
          // -->
          </script>
          </head>
          <body onLoad="SchreibeQuadrate()">
          </body>
          </html>

          Erläuterung:
          Variablen können mit Hilfe des  reservierten Wortes var definiert werden. Dieses Schlüsselwort ist zwar nicht zwingend notwendig, macht den Quellcode aber lesbarer, da es signalisiert, daß an der betreffenden Stelle eine neue Variable definiert wird. Jede Variablendefinition wird mit einem Strichpunkt abgeschlossen, genau wie eine  Anweisung (betrachten Sie eine Variablendefinition einfach als eine Anweisung!).

          Es gibt globale Variablen und Variablen, die innerhalb einer  Funktion definiert sind. Im obigen Beispiel ist die Variable Hinweis global, während die Variablen SinnDesLebens, i, x und Satzteil funktionsgebunden sind. Eine globale Variable steht jederzeit zur Verfügung, während eine Variable, die innerhalb einer Funktion definiert wird, nur innerhalb dieser Funktion zur Verfügung steht. Man spricht in diesem Zusammenhang auch von der "Lebensdauer" von Variablen.
          --------------------------------------------------------------------
          ZITAT Ende

          1. Moin!

            Hm, dann müßte zumindest auch SelfHTML an dieser Stelle korrigiert werden, wo steht, daß man das "var" genausogut weglassen kann:

            Da hast Du wohl was falsch verstanden (ist auch wirklich nicht ganz klar geschrieben). Die var-Deklaration innerhalb einer Funktion kann *nicht* weggelassen werden, denn wenn man eine Variable einfach so benutzt, wird sie automatisch global angelegt, wenn sie noch nicht besteht. Nur das var macht sie lokal, und erst damit wird eine Rekursion moeglich (sonst wuerde immer dieselbe Variable verwendet werden, was normalerweise unerwuenscht ist). Uebrigens sind Funktionsargument auch lokale Variablen.

            So long

        2. Hi,

          Sorry Emmi, aber da hat Carsten recht.

          Ja, weil Variablen, die in einer Funktion ohne den Bezeichner "var" deklariert werden, nun mal _global_ gültig sind (mein Lieblingsthema...)

          Es funzt ja jetzt und weder die Variable 'elm' noch 'x' habe ich irgendwo anders im Quelltext schon mal verwendet.

          for (var x=0; x<elm.length; x++)

          ^^^
          ich vermute, dieser Zusatz war der Grund. Denn nur dadurch wird eine _lokale_ Variable angelegt. Das ist zwingend notwendig, da x ja spezifisch für jedes Element ist.

          Grüße,
          Martin

    2. Hallo Thomas

      elm = this.Elemente;

      var elm = this.Elemente;

      sonst ist es eine globale Variable

      for (x=0; x<elm.length; x++)

      for (var x=0; x<elm.length; x++)

      dito, kann aber sein, dass das implizit schon so ist.

      Gruss,
      Carsten

      Hallo Carsten,

      ich danke Dir vielmals. Das wars. Und zwar gilt das für beide Variablen.

      Nun noch mal für mein Verständnis. Über 'var' erzeuge ich quasi eine neue Variable auf dem Stack, wohingegen wenn ich es weg lasse der Inhalt der existierenden Variablen lediglich überschrieben wird. Sehe ich das richtig? Dann macht es natürlich Sinn, das die Rekursion nicht weiter ausgeführt wird, denn die Funktion weiß ja dann nicht mehr, das da noch Elemnte folgen.

      Vielen Dank nochmal
      Thomas

      1. Hi Thomas,

        Nun noch mal für mein Verständnis. Über 'var' erzeuge ich quasi eine neue Variable auf dem Stack, wohingegen wenn ich es weg lasse der Inhalt der existierenden Variablen lediglich überschrieben wird. Sehe ich das richtig?

        Ja!

        Grüße,
        Martin

  2. Wäre es unter Umständen möglich, damit man die Funktion testen kann, auch den Rest des Codes zu posten? Die F. sieht soweit ganz vernünftig aus, aber wenn man es nicht testen kann, ist es schwer einen Fehler zu finden. Vielleicht liegt er ja auch in der Objektstruktur der verwendeten Objekte...

  3. Hi Emmi, könntest du vielleicht den kompletten quelltext zur Verfügung stellen. Dann könnte man es direkt bei sich texten und evtl. deinen Fehler schneller korrigieren.

    Gruß Urmel

    1. Hi Emmi, könntest du vielleicht den kompletten quelltext zur Verfügung stellen. Dann könnte man es direkt bei sich texten und evtl. deinen Fehler schneller korrigieren.

      Gruß Urmel

      Die Frage kommt von Thomas, nicht von mir ;-)

    2. Hi Emmi, ...

      meinte natürlich Thomas
      ..hab mir wohl beim schreiben auch ein wenig zeit gelassen. (zuviel Zeit ;)