Unterfunktionen in Übergeordneterfunktion aufrufen

Snugel

Mitglied
Hallo Forum,

vorab ich bin Beginner was Javascript angeht und bin aktuell überfordert.

Ich habe das Forum durchsucht und habe nichts gefunden was zu meiner Situation passt. Kann sein das ich falsche Suchbegriffe verwendet habe, weil ich mich nicht besser auskenne. Ich bitte um nachsehen. Eventuell kann man meinen Beitrag an entsprechende stelle verschieben.

Folgende Situation:
Ich habe ein "Sammlung.js" Datei. In diese will ich einige Funktionen, die ich in Zukunft brauche hinein schreiben.
Die Funktionen im einzelnen Funktionieren (getestet) aber alle in eine Sammlung hineinzubekommen
und dann die Werte der Unterfunktionen abzufragen das geht nicht.

Fehlerquellen:

Eigene Fehlerquellen könnten der Umgang mit Variablen sein, den die Funktionen für sich
in einem eigenen Dokument.js funktionieren.
Soweit ich weis wird unterschieden in Globale- und Lokale-Variablen.
Globale-Variablen werden durch "var xxx = " geschrieben und Lokale-Variablen durch das weglassen des "var" oder?
Heist Global dann auch, dass wenn ich aus einer Unterfunktionen, eine Globale variable aus der in der Übergeordnetenfunktion aufrufen kann?
Oder kann ich nur Globalevariablen von der Übergeordnetenfunktion in der Unterfunktion aufrufen?
Wenn letzteres der Fall ist, wie rufe ich dann Variablen aus Unterfunktionen in der Übergeordnetenfunktion auf?

Bemerkung:
Die Funktionen sind schemenhaft dargestellt. Die Inhalte der Unterfunktionen sind in ihrer fülle
deutlich inhaltsreicher. Manche Funktionen habe ich aus anderen Regionen des Internets und andere selber erstellt.
Es handelt sich immer um Funktionen.

Die Struktur sieht so aus:
Javascript:
function moaf()                         // moaf = mother of all functions
{
    funktion KWfunktion()               // In seperatem Dokument funktionierende KWfunktion
        {
        var KW1 = xxxx        //Variable KW1 beinhaltet ein Ergebnis
        }
    funktion Zeitfunktion()             // In seperatem Dokument funktionierende Datum- & Zeitfuktion
        {
        var Datum1 = xxxx    //Variable Datum1 beinhaltet ein Ergebnis
        var datum2 = cccc    //Variable Datum2 beinhaltet ein Ergebnis
        var Datum3 = yyyy    //Variable Datum3 beinhaltet ein Ergebnis
        var Zeit1 = xxxx     //Variable Zeit1 beinhaltet ein Ergebnis
        var Zeit2 = yyyy     //Variable Zeit2 beinhaltet ein Ergebnis
        }

    // Die nachfolgende Zeitstempelfunktion ist noch nicht fertig, soll aber berücksichtigt werden. Er darf sich wenn er einmal im HTML ist nicht aktualisieren. 
    function Zeitstempelfunktion()      // funktion für den Zeitstempel
        {
        var Stempel1 = xxxx  //Variable Stempel1 beinhaltet ein Ergebnis
        var Stempel2 = yyyy  //Variable Stempel2 beinhaltet ein Ergebnis
        var Stempel3 = cccc  //Variable Stempel3 beinhaltet ein Ergebnis
        }

    { // Ausgabevorbereitung
        { // KW; Die KW (nach ISO) soll sich im HTML aktualsieren
            kw1.innerHTML = KW1;        // Format: "KW: XX"
        }
        { // Datum; Das Datum soll sich im HTML aktualsieren
            date1.innerHTML = Datum1;   // Format: "Wochentag, den DD.MM.JJJJ"
            date2.innerHTML = Datum2;   // Format: "den DD.MM.JJJJ"
            date3.innerHTML = Datum3;   // Format: "DD.MM.JJJJ"
        }
        { // Zeit; Diese soll sich egal in welchem Format sekündlich aktualisieren
            time1.innerHTML = Zeit1;    // Format: "um hh:mm:ss"
            time2.innerHTML = Zeit2;    // Format: "hh:mm:ss"
        }

       // Die nachfolgenden Stempelaufrufe sind noch nicht fertig, sollen aber berücksichtigt werden.
        { // Stempel; Dieser darf sich im HTML nicht verändern, wenn er einmal gesetzt wurde
            stamp1.innerHTML = Stempel1;  // Format: "Wochentag, den DD.MM.JJJJ um hh:mm:ss"
            stamp2.innerHTML = Stempel2;  // Format: "den DD.MM.JJJJ um hh:mm:ss"
            stamp3.innerHTML = Stempel3;  // Format: "DD.MM.JJJJ hh:mm:ss"
        }
    }
    setTimeout("moaf()",1000);
}
window.setTimeout("moaf()",1000);


Nachdem ich die Funktionen so verschachtelt habe, will ich nun im HTML-Dokument
das js-File im head des HTML-Dokuments einbinden.
Um die Funktionen verfügbar zu machen Modifiziere ich den body-Tag HTML-Dokuments.
Um die Werte der Unterfunktionen aufzurufen, will ich die IDs in einem span (kann anstelle von div verwendet werden und hat auch funktioniert) aufrufen.
Das sollte dann wie folgt aussehen:
HTML:
<!DOCTYPE HTML>
    <html>
        <head>
            <script src="js/Sammlung.js" type="text/javascript"></script>
        </head>

        <body onload="moaf()">
            <span id="kw1"></span>
            <br>
            <span id="date1"></span>
            <br>
            <span id="date2"></span>
            <br>
            <span id="date3"></span>
            <br>
            <span id="time1"></span>
            <br>
            <span id="time2"></span>
            <br>
            <span id="stamp1"></span>
            <br>
            <span id="stamp2"></span>
            <br>
            <span id="stamp3"></span>
        </body>
    </html>



Der Wille es selber zu schaffen war da, jetzt bin ich verzweifelt weil ich es selber nicht hinbekomme.
Ich würde mich sehr freuen wenn sich meiner jemand annehmen kann.
Ich danke im voraus.

Falls Infos fehlen einfach melden.

Beste grüße vom Bodensee
Snugel
 
Hallo Snugel, willkommen im Forum! :)

Soweit ich weis wird unterschieden in Globale- und Lokale-Variablen.
Kann man so machen. Präziser finde ich es, jeder Variablen einen Gültigkeitsbereich (Scope) zuzuweisen. Zur Laufzeit gibt es dann eine Hierarchie von solchen Scopes, die Variable des innersten wird immer präferiert. Außerdem gibt es einen äußersten Scope, wenn ich mich nicht vertue, müsste das im Browserumfeld das window-Objekt (bei Node.js global) sein. Variablen des äußersten Scopes nennt man global.
Wenn du in deiner übergeordneten Funktion eine Variable anlegst, die natürlich sichtbar in jeder untergeordneten Funktion ist, dann ist diese auch global - jetzt jedoch in einem anderen Sinne, und zwar, dass verschiedene Komponenten deiner Software darauf lesend und/oder schreibend zugreifen. Was nun eine Komponente ist (eine untergeordnete Funktion, eine Datei/Modul [im ES 6 Sinn] oder gar mehrere Dateien) hängt vom Betrachter ab.
Die Anzahl globaler Variablen möchtest du zwecks Wartbarkeit, Sauberkeit und Testbarkeit deiner Software generell vermeiden.

Globale-Variablen werden durch "var xxx = " geschrieben und Lokale-Variablen durch das weglassen des "var" oder?
Andersrum.
Beachte jedoch, dass Variablen mit "var" funktionsweit gelten, d. h.
Javascript:
function foo(x) {
  if (x > 3) {
    var myVar = 'Hello';
  }
  // ... viel Code ...
  // Idee nun: wenn x > 5, gebe Goodbye zurück, sonst 'undefined' (d. h. den Wert, welche eine uninitialisierte Variable zugewiesen bekommt)
  var myVar;
  if (x > 5) {
    myVar = 'Goodbye';
  }
  return myVar;
}
foo(4); // Wird 'Hello' zurückgeben
Das liegt am sog. Hoisting des vars.

Ab ES 6 gibt das 'let'-Statement, was wirklich block-scoped ist, d. h. "let myVar" im ersten if würde wirklich nur myVar im ersten if etwas zuweisen. Ich nutze selbst nur noch "let" und würde das auch so empfehlen. (Außer vielleicht für wirklich globale Variablen beim window/global-Objekt im Browser/Node.js, siehe http://2ality.com/2015/02/es6-scoping.html#the-global-object)

Heist Global dann auch, dass wenn ich aus einer Unterfunktionen, eine Globale variable aus der in der Übergeordnetenfunktion aufrufen kann?
Ja. Auf Variablen und Funktionen aus einem übergeordneten Gültigkeitsbereich kannst du zugreifen. Hättest du Stempel1, Stempel2 usw. in der äußeren Funktion mit "var" (oder auch "let") deklariert, dann würden die Werteänderungen aus Zeitstempelfunktion in der Tat sichtbar werden, nachdem Zeitstempelfunktion einmal aufgerufen wird (was in deinem Code nicht passiert).

Oder kann ich nur Globalevariablen von der Übergeordnetenfunktion in der Unterfunktion aufrufen?
Die Frage verstehe ich nicht genau. Du hast einen "shared global state" zwischen der übergeordneten und untergeordneten Funktionen, d. h. beide können lesend und schreiben darauf zugreifen und beide bemerken die Wertänderungen.

Javascript:
window.setTimeout("moaf()",1000);
setTimeout erwartet eine Funktion als erstes Argument, die String Übergabeoption ist veraltet (und hat einige Nachteile, kannst du auf MDN unter setTimeout nachlesen):
Javascript:
window.setTimeout(moaf, 1000);
Wenn du aus dem onload-Event heraus moaf aufrufst, brauchst du den initalen Timer in Zeile 47 nicht mehr. Aktuell hast du also 2 parallel laufende Timer.
 
Das hört sich an wie OOP in Javascript.

Quasi:

Code:
function moaf () {
    this.attribut1 = 'blabla';
    this.attribut2 = "blabla";
    this.methode1 = function() {
        return this.attribut1 + '<- 1 ' + this.attribut2 + ' <- 2 #';
    };
    this.methode2 = function(parameter) {
        return 'Attr1:' + this.attribut1 + ' Attr2:' + this.attribut2 + ' parameter:' + parameter;
    };
}


var moafVar = new moaf();

alert(moafVar.methode1() + moafVar.methode2('asd'));
 
Das hört sich an wie OOP in Javascript.
Nachdem @Snugel von sich selbst sagt, dass er Anfänger sei, will ich ihn nicht mit jedem Feature, das in älterer Literatur vielleicht unerwähnt bleibt, zuballern, aber bei OOP sollte man schon im Hinterkopf behalten, dass jeder aktuelle Browser mit EcmaScript Standard 5 auch echte Klassen unterstützt: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Klassen :)
Ausgenommen IE 11, aber dieser wird ja durch Microsoft Edge 'offiziell' abgelöst.

Wobei es sicherlich nicht schaden kann, "this.attr = xyz" im Kontext einer Funktion auch zu verstehen.
 
Hallo Forum!

Bitte entschuldigt das ich mich aktuell nicht so oft sehen lasse. Bin sehr im Stress. Ich danke aber an dieser Stelle für die Antworten. Am Wochenende finde ich sehr wahrscheinlich mehr Zeit und werde mich dann konkret mit den Antworten auseinander Setzen.

Vielen dank an alle.
 
Hallo Forum.

Danke für die vielen Antworten. Ich erkenne eben das ich mich eventuell übernommen habe, wenn ich mir die Antworten so anschaue.
Ich glaube ich bin nicht in der Lage das alles nachzuvollziehen was so auf mich ein Strömt.

Ich weis nicht was der richtige Weg ist, aber gibt es eine Möglichkeit einfach und verständlich anhand eines Beispiels hier im Forum aufzuzeigen was Ihr meint. Vielleicht auch mit direktem Bezug auf meine Fehler so wie es ComFreak macht? Zeilennummer: ..., Falsch ist: ..., Richtig wäre: ...

Gerne würde ich es für den Anfang einfach halten. Soll heisen: Ich würde gerne das Script erst mal soweit fertigmachen das funktioniert. Feinheiten wie Klassen etc. will ich im Anschluss behandeln.

Ich versuche es nun etwas einfacher für mich zu halten.
Script-Beispiel:
Javascript:
//Dokument-Name: moaf.js

funktion kwAngaben()
{
     {// KW Ausgabeformatierung
     // var KW beinhaltet ein Ergebnis, welches sich aus einem Textteil "KW: " der Überprüfung ob eine Null führend ist oder nicht und dem Ergebnis aus der Variablen "aktuellKW"
          var KW =  "KW: " + ((aktuellKW < 10) ? "0" : "") + aktuellKW;          // Format KW:     "KW: XX"
     }
     {//Ausgabevorbereitung
          kw.innerHTML = KW;          // für den Aufruf mit einer id in einem span
     }
     setTimeout(kwAngaben(),1000);
};
window.setTimeout(kwAngaben());


funktion zeitAngaben()
{
     {// Zeit Ausgabeformatierung
          // var Zeit beinhaltet ein Ergebnis, welches sich aus "aktuellWochentag", einem Textteil ", den " und dem Ergebnis aus der Variablen "Datum" zusammenstellt
          var Datum1 = aktuellWochentag + ", den " + Datum;          // Format Datum1:     "Wochentag, den DD.MM:JJJJ"
          // var Zeit beinhaltet ein Ergebnis, welches sich aus einem Textteil ", den " und dem Ergebnis aus der Variablen "Datum" zusammenstellt
          var Datum2 = ", den " + Datum;                                            // Format Datum2:     "den, DD.MM:JJJJ"
          // var Zeit beinhaltet ein Ergebnis, welches sich aus dem Ergebnis aus der Variablen "Datum" zusammenstellt
          var Datum3 = Datum;                                                            // Format Datum3:     "DD.MM.JJJJ"
     }
     {//Ausgabevorberietung
          date1.innerHTML = Datum1;
          date2.innerHTML = Datum2;
          date3.innerHTML = Datum3;
     }
     setTimeout(zeitAngaben(),1000);
};
window.setTimeout(zeitAngaben());


Im HTML-Dokument rufe ich das nun so auf:
HTML:
<!DOCTYPE HTML>
    <[html>
        <head>
            <script type="text/javascript" src="js/moaf.js"></script>
        </head>

        <body>
            <script type="text/javascript">kwAnagben();</script>
            <br>
            <script type="text/javascript">zeitAngaben(Datum1)</script>
            <br>
            <script type="text/javascript">zeitAngaben(Datum2)</script>
        </body>
    </html>
Leider funktioniert das nicht.

Ich hoffe ich sorge nicht für Unmut oder Ärger. Vielen Dank.
 
Zuletzt bearbeitet:
Muss noch was hinzufügen.
Das ist nicht der vollständige Code, es handelt sich dabei nur um die Variablen, welche die Ergebnisse beinhalten.
 
Schreibfehler in Zeile 8 des HTML.

In Zeile 10 und 12 des HTML rufst Du die Funktion zeitAngaben mit einem Parameter auf. Du hast sie jedoch zuvor im Javascript ohne Parameter definiert. Datum1 und Datum2, die Du jeweils als Parameter übergibst, werden innerhalb dieser Funktion ermittelt, da beißt sich die Katze in den Schwanz.

Leider ist mir nicht ganz klar, was Du mit dem Code vor hast, so dass ich dir keine Lösung anbieten kann.
 
Entschuldigt bitte meine unklaren Worte.

Kurz gesagt will ich Werte aus einer Variablen in einem HTML aufrufen.

Ursprünglich handelte es sich um eine übergeordnete Funktion, die mehrere untergeordnete (verschachtelte) Funktionen enthielt. Nicht wissend, dass "onload" veraltet oder nicht mehr zu den best practice gehört, wollte ich statt drei Funktionsaufrufen im Body-Element des HTML nur eine Funktion im Body-Element aufrufen. Das sollte via "onload" geschehen. Die übergeordnete Funktion nannte sich "moaf" und das Dokument ursprünglich "Sammlung.js".
Nach dem ich nun weis, dass "onload" nicht mehr verwendet werden soll, habe ich mich gefragt wie kann ich dann die Funktion anziehen. Die Antwort die ich für mich fand war: es ist nicht nötig sie über "onload" anzuziehen. Es genügt der Verweis auf die Datei die sich nun "moaf.js" nennt im Head-Element. Im Body-Bereich rufe ich die Ausgabe dann nur über die Id auf.

Nun habe ich soeben den entscheidenden Durchbruch erzielt. Allerdings ohne das verschachteln von Funktionen wie es in meinem Titel mehr oder weniger erkennbar ist.
Ich habe festgestellt, dass das verschachteln von Funktionen beim aufrufen im Browser Performance Einbusen mit sich bringt.
Dank Euch habe ich nun erkannt, dass es nicht mehr üblich ist das über "onload" zu tun. Danke an alle!
Außerdem unterlag ich einem zusätzlichen Irrglauben.

Nun aber zu meiner einfachen Lösung, die ich Euch nicht vorenthalten will:
Grundsätzlich will ich nur Werte aus Variablen in einem HTML-Dokument wiedergeben. Das habe ich nun nach einem bestimmten Schema hinbekommen.

Bei den Variablen handelt es sich um Zeitwerte

Javascript:
     {// Globale Variablen deklarieren (die enthaltenen werte will ich wiedergeben)
          var KW
          var Datum1
          var Datum2
          var Datum3
          var Zeit1
          var Zeit2
     }
     function kwAngabe ()
     {// hierdurch füllt sich die Variable "KW"
          // Das ist ein Platzhalter für einige Zeilen JavaScript-Code
          {// Ausgabe KW
               kw.innerHTML = KW;     die Buchstabenfolge "kw" ist die "ID", welche benötigt wird um die Werte im HTML wiederzugeben
          }
          return setTimeout("kwAngabe()", 1000);

     };
     window.setTimeout("zeitAngabe()");


     function zeitAngabe ()
     {// durch die Funktion füllen sich die Variablen "Datum1", "Datum2", "Datum3", "Time1" und "Time2"
          // Das ist ein Platzhalter für einige Zeilen JavaScript-Code
          {// Ausgabe Uhrzeit
               date1.innerHTML = Date1;     die Ziffernfolge "date1" ist die "ID", welche benötigt wird um die Werte im HTML wiederzugeben
               date2.innerHTML = Date2;     die Ziffernfolge "date2" ist die "ID", welche benötigt wird um die Werte im HTML wiederzugeben
               date3.innerHTML = Date3;     die Ziffernfolge "date2" ist die "ID", welche benötigt wird um die Werte im HTML wiederzugeben
          }
          {// Ausgabe Uhrzeit
               time1.innerHTML = Zeit1;     die Ziffernfolge "time1" ist die "ID", welche benötigt wird um die Werte im HTML wiederzugeben
               time2.innerHTML = Zeit2;     die Ziffernfolge "time2" ist die "ID", welche benötigt wird um die Werte im HTML wiederzugeben
          }
          return setTimeout("kwAngabe()", 1000);
     };
     window.setTimeout("zeitAngabe()");

Der Aufruf im HTML sieht dann ohne onload so aus:
HTML:
<!DOCTYPE HTML>
    <[html>
        <head>
            <script src="js/moaf.js" type="text/javascript"></script>
        </head>

        <body>
            <span id="kw"></span>
            <br>
            <span id="date1"></span>
            <br>
            <span id="date2"></span>
            <br>
            <span id="date3"></span>
            <br>
            <span id="time1"></span>
            <br>
            <span id="time2"></span>
        </body>
    </html>

Die Frage ist jetzt nur noch, ob es sich bei den folgenden Angaben um guten Stiel handelt:
kw.innerHTML = KW;
return setTimeout("kwAngabe()", 1000);
window.setTimeout("kwAngabe()");
<span id="kw"></span>

Viele dank für Eure Geduld und Bemühungen.
 
Zuletzt bearbeitet:
Auf das onload kann man i. allg. verzichten, wenn man das Javascript an das Ende des body stellt. Dann sind alle HTML-Elemente da und man kann damit arbeiten.
Du hast das Skript aber im head eingezogen. Ich vermute, dass Du deswegen die setTimeouts brauchtest, weil dort die HTML-Element noch nicht existieren. Allerdings fehlt bei deinen setTimeouts teilweise die Angabe des Intervalls.
Außerdem kann ich nicht erkennen, wo die Variablen Date1, Date2 und Date3 definiert sind. Oben sind nur Datum1, Datum2 und Datum3 definiert, aber ohne Wertzuweisung.
Und an einigen Stellen fehlen Kommentarzeichen.
Bist Du sicher, dass das so funktioniert?
 
Zurück