romero: technisches Verständnis zu "return" in Funktionen

hallöchen auch,

ich hab da mal eine technische verständnisfrage zu return.

das return dient doch dazu werte einer funktion zurückzugeben.also werte,welche in der funktion erstell,errechnet,... wurden, z.b. in eine andere funktion zu übergeben.

bsp.:

function basis()  
{  
  var a,b,c;  
  
  a = test_a();  
  b = test b( a );  
  ...  
};  
  
//--> weitere Funktionen  
function test_a()  
{  
  var wert_a = 2+5;  
  
  return wert_a;  
};  
  
function test_b( wert_aus_function )  
{  
  var wert_b = wert_aus_function+10;  
  
  return wert_b;  
};

wenn ich aber in der function basis() ein,z.b.,onclick drin habe,bewirkt ja das return (auf das onclick bezogen) nur soviel,das der browser ein true oder false zurückgibt,also angeklickt ja/nein.

wie kann ich also bewirken,das bei einem onclick ein wert geändert wird und dieser für die function basis() zurückgeben wird?

das er an der stelle wartet bis es ein klick macht,erstelle ich mittels settimeout.aber die frage ist,wie kann ich es so erstellen das er erst nach dem klick weiter läuft?soweit ich weiß,läuft erstmal alles durch ehe ich was anklicken oder allgemein steuern kann.

mein bsp. dazu:
dazu sei gesagt,das ich jetzt so schreibe,wie ich denke.also den logischen ablauf.den dazugehörigen code weiß ich natürlich nicht und wollt dazu euch fragen,wie er aussehen könnt.

function basis()  
{  
  var a,b,c;  
  
  a = test_a();  
  
  test_b( "egal ob mit oder ohne variablen" );  
  function schleife()  
  {  
    //--> Werte ermitteln und auch zurückgeben  
    //--> Wohin werden die Werte zurückgegeben  
    var button = "gedrückt";  
    return button;  
  };  
  function weiter()  
  {  
    window.setTimeout( schleife, 0 );  
  };  
  function test_b( wert );  
  {  
    document.getElementById( "id_button" ).onclick = function() { weiter() };  
  };  
  
  //--> hier soll der Wert button (="gedrückt") in die var b gespeichert werden und für die nächste funktion genutzt werden  
  
  c = test_c( a, b );  
  ...  
};  
  
//--> weitere Funktionen  
function test_a()  
{  
  var wert_a = 2+5;  
  
  return wert_a;  
};  
  
function test_c( wert_aus_function, gedrückt )  
{  
  if( gedrückt == "gedrückt" )  
  {  
    var wert_c = wert_aus_function+10;  
  };  
  return wert_c;  
};

gibts da irgendwie ne lösung?weil wollte keine funktions-verschachtelungen haben sondern ne übersichtliche struktur.weil müsste ja in der function schleife() bzw function weiter() weiter gehen mit meinen weiteren funktionen.

lg romero

  1. Moins,

    also erstmal ganz langsam.
    Ein return gibt keinen Wert an eine andere Funtion zurück, sondern an den Aufrufer!

    Das warten auf ein Event brauchst du nicht selber programmieren, sowas gibts schon seit der ersten Stunde von Javascript. Dass nennt sich dann Eventhandler. Dein Click ist z.B. einer von vielen.
    Ein Eventhandler stößt beim eintreffen dieses Events eine Funktion an.

    z.B.

    function test()
    {
        alert("ich wurde geclickt!");
    }

    object.onclick = test();
    Nach einem Klick auf das "object" (welches ein HTML Element sein sollte) erhälst du eine entsprechende Nachricht.

    Eventuell überarbeitest du nochmal dein Script und stellst anschliessend nochmal eine Frage ;).

    Gruß
    schöner Tag heute "juhu"
    T-Rex

    1. function test()
      {
          alert("ich wurde geclickt!");
      }

      object.onclick = test();

      Häufiger Fehler: Handler-Funktion direkt aufrufen

      Mathias

      1. nachtrag: warum das ganze?

        ich habe mehrere radiobuttons.je nach dem was ich anklicke kommt eine abfrage bestätigen/abbrechen (radiobuttons werden entsprechend neu gesetzt) aber nicht mittels alert() oder confirm() sondern mit object.innerHTML.

        und da ich das dann nicht immer neu abfragen wollte,wollte ich das ganze als variable bzw in einem array() speichern um es später für weitere funktionen zu nutzen,die aber nicht innerhalb dieses onclick-konstruktes stehen.

        darum geht es mir.aber wenn technisch nicht geht,bleibt mir da leider nix anderes übrig als am ende oder für jede weitere funktion diese erneut zu erfragen.

        lg romero

        1. Hallo,

          aber wenn technisch nicht geht,bleibt mir da leider nix anderes übrig als am ende oder für jede weitere funktion diese erneut zu erfragen.

          Es geht ganz einfach, indem du in deinem Event-Handler einen Array abänderst, auf welchen die besagten später ausgeführten, weiteren Funktion ebenfalls Zugriff haben. Scheitert es daran?

          Deine Beispiele nutzen verschachtelte Funktionen bereits, um Variablen zwischen Funktionsaufrufen zu teilen. Das ist eine Möglichkeit, welche hinsichtlich Kapselung optimal ist. Das Erzeugen eines lokalen Scopes, in dem man geteilte Variablen deklarieren kann, ist mit einer Wrapper-Funktion möglich. In deinem Beispiel erfüllt »basis« bereits diese Rolle. Im Prinzip kann so eine Wrapper-Funktion auch anonym sein und direkt ausgeführt werden - das ist der Standard bei JavaScript-Bibliotheken.

          Eine andere Möglichkeit wäre das Speichern dieses Arrays an irgendeiner zentralen Stelle. Dafür musst du dich mit dem Unterschied zwischen lokalen und globalen Variablen auseinandersetzen. Das Gruppieren von eigenen Objekten/Funktionen in einem eigenen »Namensraum« ist z.B. mit einem Object möglich.

          Mathias

          1. Es geht ganz einfach, indem du in deinem Event-Handler einen Array abänderst, auf welchen die besagten später ausgeführten, weiteren Funktion ebenfalls Zugriff haben. Scheitert es daran?

            nein das nicht,aber ich müsste ja in der vom eventhandler ausgeführten funktion bleiben,damit der geänderte wert auch seine gültigkeit besitzt.

            sobald ich aber den wert auch ausserhalb des eventhandlers benutzen würde,würde da der "alte" wert verarbeitet werden.

            aber mittlerweile lässt sich die verschachtelung halt nich vermeiden.wollte halt es so einfach wie möglich halten.aber nunja.wieder was gelernt :)

            lg romero

    2. hy auch

      function test()
      {
          alert("ich wurde geclickt!");
      }

      object.onclick = test();
      Nach einem Klick auf das "object" (welches ein HTML Element sein sollte) erhälst du eine entsprechende Nachricht.

      das ist mir schon klar.aber was ist wenn ich da z.b. in der function test() ein array() erstellen möchte,dieses dann aber wie gesagt an die basis-funktion übergeben möchte,wie mache ich das?

      um dein bsp. aufzugreifen:

      function basis()  
      {  
        var testen = new array();  
        
        function test( testen )  
        {  
           testen.push( 1,2,3,4,5,... );  
        }  
        
        object.onclick = function() { test( testen ); };  
        
        neuer_test = weiterer_test( testen );  
        //--> hier hat das array testen immer den inhalt 0  
      };
      

      --> alles ungetestet!!!

      wenn ich aber es umschreibe,nämlich so:

      function basis()  
      {  
        var testen = new array();  
        
        function test( testen )  
        {  
           testen.push( 1,2,3,4,5,... );  
        
           neuer_test = weiterer_test( testen );  
        }  
        
        object.onclick = function() { test( testen ); };  
      };
      

      dann sieht das array testen so aus: 1,2,3,4,5,...
      ich wollte wie gesagt unnötige verschachtelungen vermeiden.aber wenn es über dieses eventhandler onclick nicht geht,muss ich diese funktion-verschachtelung machen.

      lg romero

      Gruß
      schöner Tag heute "juhu"
      T-Rex

      ja endlich!!!

      1. Hallo,

        function basis()

        {
          var testen = new array();

        function test( testen )
          {
             testen.push( 1,2,3,4,5,... );
          }

        object.onclick = function() { test( testen ); };

        neuer_test = weiterer_test( testen );
          //--> hier hat das array testen immer den inhalt 0
        };

          
        Bitte werde dir bewusst, warum das nicht funktioniert und was das Registrieren von Event-Handlern bedeutet.  
          
        Es bedeutet NICHT, dass das Programm ANHÄLT und auf das Ereignis WARTET.  
          
        Es bestimmt vielmehr eine Funktion, die in ihrem eigenen, losgelösten Kontext ausgeführt wird, WENN irgendwann später das Ereignis passiert.  
          
        
        > ~~~javascript
        
        function basis()  
        
        > {  
        >   var testen = new array();  
        >   
        >   function test( testen )  
        >   {  
        >      testen.push( 1,2,3,4,5,... );  
        >   
        >      neuer_test = weiterer_test( testen );  
        >   }  
        >   
        >   object.onclick = function() { test( testen ); };  
        > };
        
        

        Von der Idee her ist das schon richtiger.

        dann sieht das array testen so aus: 1,2,3,4,5,...
        ich wollte wie gesagt unnötige verschachtelungen vermeiden.aber wenn es über dieses eventhandler onclick nicht geht,muss ich diese funktion-verschachtelung machen.

        Ja und nein: Das ist ein grundlegendes Problem der asynchronen Arbeitsweise und es gibt verschiedene Lösungsansätze.

        Wenn du z.B. drei Vorgänge hast, die streng nacheinander erfolgen müssen, weil jeder Vorgang das Ergebnis des vorherigen benötigt, aber alle Vorgänge asynchron durch Events gestartet werden: Dann brauchst du zumindest *von der Struktur her* eine Verschachtelung. Und du musst ggf. mit Statusvariablen den Fortschritt verfolgen.

        Man *kann* in die Versuchung kommen, das alles in verschachtelten Funktionen zu notieren. Sinnvollerweise tut man das nicht, sondern splittet die Vorgänge in kleine Funktionen auf, die man untereinander notiert und die sich gegenseitig aufrufen bzw. als Event-Handler und Callbacks dienen.

        Wie man das im konkreten Fall sinnvoll umsetzt, kann man nicht vorhersagen. Allgemein sollte man Verschachtelung vermeiden und kann den Code »links halten« (wenig Einrückungen = wenig Verschachtelungen).

        Mathias

        1. Hallo,

          function basis()

          {
            var testen = new array();

          function test( testen )
            {
               testen.push( 1,2,3,4,5,... );
            }

          object.onclick = function() { test( testen ); };

          neuer_test = weiterer_test( testen );
            //--> hier hat das array testen immer den inhalt 0
          };

          
          >   
          > Bitte werde dir bewusst, warum das nicht funktioniert und was das Registrieren von Event-Handlern bedeutet.  
          >   
          > Es bedeutet NICHT, dass das Programm ANHÄLT und auf das Ereignis WARTET.  
          >   
          > Es bestimmt vielmehr eine Funktion, die in ihrem eigenen, losgelösten Kontext ausgeführt wird, WENN irgendwann später das Ereignis passiert.  
          >   
            
          ich glaube,wurde vorher schon geklärt,warum es nicht funktionieren kann.  
            
          
          > Wenn du z.B. drei Vorgänge hast, die streng nacheinander erfolgen müssen, weil jeder Vorgang das Ergebnis des vorherigen benötigt, aber alle Vorgänge asynchron durch Events gestartet werden: Dann brauchst du zumindest \*von der Struktur her\* eine Verschachtelung. Und du musst ggf. mit Statusvariablen den Fortschritt verfolgen.  
          >   
            
          bei den aufeinanderbauenden funktionen ist das mit dem return-werten und der verschachtelungen schon klar.  
            
          es ging mir auch um die übersicht,damit sich andere,die sich den code anschauen,auch zurechtfinden.je mehr verschachtelt wird,desto schlimmer ist der überblick über das gesamtbild  
            
          lg romero
          
  2. Hallo,

    Wir hatten deine Frage anscheinend schon im Thread  </archiv/2011/7/t206186/>. Dort hatte JürgenB eigentlich sehr schön erklärt, dass dir anscheinend noch das Verständnis für Event-basierte Programmabläufe fehlt und dass du damit auf basaler Ebene herumexperimentieren solltest. Dein jetzige Code scheint schon so ein Experiment zu sein, allerdings fehlt wohl noch die entscheidende Wendung.

    Was du anscheinend vorhast ist folgendes:

    1. Mache etwas
    2. Warte auf eine Benutzereingabe
    3. Fahre mit der Verarbeitung fort

    Wie Jürgen gesagt hat, kannst du so ein Problem nicht mit Rückgabewerten lösen. Vergiss Übergabe- und Rückgabewerte erst einmal völlig. Diese sind interessant, wenn ein Programm dauerhaft läuft und aktiv auf irgendetwas wartet. Das ist bei JavaScript-Programmen eigentlich nie der Fall. JavaScripte laufen vielleicht mal für ein paar hundert Milisekunden und warten dann auf irgendwelche Ereignisse. Ein JavaScript-Interpreter verfügt über eine Event-Loop, das ist eine Ausführungs-Warteschlange für Funktionen. Und so eine Funktion macht möglichst immer nur eine kleine Sache, dann beendet sie sich.

    Bei Event-Handling kommt das Programm ständig zum Stillstand und wird bei einem Event auch nicht an der alten Stelle fortgesetzt, sondern es wird eine Handler-Funktion aufgerufen. Bitte mach dich damit mal vertraut. Wie gesagt: Ein Event-Handler kann keine Daten »zurückgeben«, aber er kann den Wert von gewissen zentralen Variablen ändern und andere Funktionen aufrufen. Vielleicht hilft dir folgendes einfaches Beispiel weiter:

    http://jsfiddle.net/gtBbh/

    Es gibt hier eine Art »Schleife«, aber nicht im üblichen Sinne (while). Es gibt auch keine Funktionen, die irgendetwas zurückgeben. Es gibt die Event-Handler-Funktion, die jeweils einen Schritt der Verarbeitung durchführt. Der ist in dem Fall sogar recht einfach, da prompt() eine der wenigen Funktionen ist, die die Welt (die Ausführung sämtlicher Scripte im Dokument) anhält. Am Ende dieser Schritt-Funktion wird ein Zähler erhöht, sodass beim nächsten Mal mit das folgende Item bearbeitet wird. Dieser Zähler ist eine Variable in der äußeren Funktion init. Die Handlerfunktion kann auf diese Statusvariable zugreifen und sie abändern. Es kann natürlich viele solcher Variablen geben, um sich den letzten Zustand zu merken und mit der Verarbeitung genau dort weiterzumachen, wo man aufgehört hat. Diese Variablen sollten irgendwo zentral notiert werden. Im Beispiel einfach in der darüberliegenden Funktion, sodass alle Funktionen darin sie mit der äußeren teilen. Diese Kapselung ist empfehlenswert.

    Mathias

    1. Was du anscheinend vorhast ist folgendes:

      1. Mache etwas
      2. Warte auf eine Benutzereingabe
      3. Fahre mit der Verarbeitung fort

      genau so sollte es sein.deshalb hieß ja auch dieses thread technisches verständnis.

      ich weiß das ich die übergeordneten werte mittels der eventhandler ändern kann und es auch teilweise schon tu aber ich dachte halt daran diese werte auch in die "ausgangsfunktion" zurückzugeben und dann mit dieser fortzufahren.

      Bei Event-Handling kommt das Programm ständig zum Stillstand und wird bei einem Event auch nicht an der alten Stelle fortgesetzt, sondern es wird eine Handler-Funktion aufgerufen. Bitte mach dich damit mal vertraut. Wie gesagt: Ein Event-Handler kann keine Daten »zurückgeben«, aber er kann den Wert von gewissen zentralen Variablen ändern und andere Funktionen aufrufen. Vielleicht hilft dir folgendes einfaches Beispiel weiter:

      ok,das leuchtet mir nun ein.also kann ich nur in der hierarisch 1. funktion,welche der eventhandler aufruft,neue funktionen aufrufen,die dann u.u. mit rückgabewerten arbeiten und auch verarbeiten.aber alles was ich da eventuell zurückgeben möchte,geht nicht.

      http://jsfiddle.net/gtBbh/
      Mathias

      ein beispiel was ich damals schon vergeblich suchte.vielen dank.

      ich wollte halt das ich mit einem eventhandler array's erstelle,werte neu definiere und sie dann in die basisfunktion übergebe um sie an einer anderen stelle erneut zu verwenden.

      vielen dank für die wunderbare erklärung.weil mit eigenen worten ist es dann doch noch verständlicher.jürgen hatte u.a. erklärt, wie mittels einem event eine schleife starte.was mir ebenfalls sehr geholfen hat.

      vielen dank auch dafür.

      lg romero