Michael N.: Art der Uebergabe von Variablen zwischen Funktionen

Hallo Forumskollegen/Innen,

ich habe jetzt ein "kleines" ;-) Problem, fuer das ich Eure Hilfe in Anspruch nehmen moechte.

In Javascript ist es normalerweise so, dass bei einer Variablenuebergabe zwischen zwei Funktionen nur der Wert uebergeben wird z.B.:

function FSUB(A, B)
{
   var C=A;
   A=B;
   B=C;
}

function FMAIN()
{
   var A = 10;
   var B = 20;
   alert("A=" + A );
   alert("B=" + B );
   FSUB(A, B);
   alert("A=" + A);
   alert("B=" + B);
}

Nun will ich einen "Call by Reference" unter JavaScript realisieren. Dazu habe ich mal das Archiv befragt, keine Antwort, dann mein Kompendium namens "JavaScript Guide" vom Netscape Navigator, ebenfalls keine Antwort und nun versuche ichs ueber die groesste "Knowledge Base", die mir zur Verfuegung steht.

NB: Unter C geht das "Call by Reference" ueber Pointer, vielleicht gibt es sowas auch unter JavaScript als "undocumentated Feature", wenn nicht habe ich natuerlich ein Problem, da ich den Dreieckstausch, den ich realisieren will dann natuerlich N-mal kopieren muss und nicht ganz elegant in eine Funktion auslagern kann (Es gibt ja auch keine Standardfunktion, die sowas macht, das hab ich natuerlich auch schon kontrolliert).

Vielen Dank

Bis danndann

Michael N.

  1. function FSUB(A, B)
    {
       var C=A;
       A=B;
       B=C;
    }

    function FMAIN()
    {
       var A = 10;
       var B = 20;
       alert("A=" + A );
       alert("B=" + B );
       FSUB(A, B);
       alert("A=" + A);
       alert("B=" + B);
    }

    Hallo,

    ich weiß zwar nicht, ob ich so ganz gerafft habe, was Du willst, aber versuchen kann man's ja mal.

    Deklariere Deine Variablen global:

    <script language="JavaScript">
    <!--
    var a = 0;
    var b = 0;

    function FSUB(newb, newa)
    {
        a=newa;
        b=newb;
    }

    function FMAIN()
    {
        a = 10;
        b = 20;
        alert("A=" + a );
        alert("B=" + b );
        FSUB(a, b);
        alert("A=" + a);
        alert("B=" + b);
    }

    Das ist zwar kein Call by Ref, aber den von Dir beschriebenen Zweck erfüllt es (glaube ich zumindest).

    Tschau, Stefan

    1. Hallo Stefan,

      Deklariere Deine Variablen global:

      Das hilft mir nicht, da ich fuer meinen Zweck keine globalen Variablen verwenden kann.

      Das ist zwar kein Call by Ref, aber den von Dir beschriebenen Zweck erfüllt es (glaube ich zumindest).

      Gerade dadurch, dass ich an der Stelle nicht mit globalen Variablen arbeiten kann erfuellt es den Zweck nicht.

      Trotzdem vielen Dank fuer Deine Muehe.

      Michael N.

  2. Hallo Michael,

    ich habe eine Lösung deines Problems und hoffe, dass du sie nutzen kannst.

    Ich gege davon aus, das du zwei Variablen vertauschen möchtest. Dein Problem war, dass man unter JS nur eine Variable als "return" - Wert zurückgeben kann.

    Hier der funktionierende Quelltext:

    <html>
    <head>
      <script language="Javascript">
       function rec(a, b)
        {
         this.a=a;
         this.b=b;
        }
       function exchange(c)
        {
         var h = c.a;
         c.a = c.b
         c.b = h
         return c;
        }
       function display()
        {
         myvar = new rec(3, 4);
         document.writeln(myvar.a, '   ', myvar.b, '<br>');
         myvar = exchange(myvar);
         document.writeln(myvar.a, '   ', myvar.b);
        }
      </script>
    </head>
    <body>
      <script language="Javascript">
       display();
      </script>  
    </body>
    </html>

    Wie funktionierts?

    Ich definiere ein neues Objekt namens "rec", welches zwei Variablen enthält. (also sowas wie ein Record)
    Die "exchange" Funktion nimmt nun diesen Record, vertauscht die beiden inneren Variablen und gibt ihn wieder aus.
    Die "display" Funktion verdeutlicht die Funktionsweise anhand der beiden Werte: (3, 4).

    Ich hoffe, dass du meine Lösung anwenden kannst.

    ALEX

    P.S. Und es geht doch in JS!

    1. Hallo ALEX,

      ich habe eine Lösung deines Problems und hoffe, dass du sie nutzen kannst.

      Leider nicht zu 100%.

      Ich gege davon aus, das du zwei Variablen vertauschen möchtest. Dein Problem war, dass man unter JS nur eine Variable als "return" - Wert zurückgeben kann.

      Du gehst von der richtigen Praemisse aus. Ich _muss_ dabei aber gleichzeitig natuerlich auch noch den Code straff halten, das heisst in der aufrufenden Funktion genau einen Call fuer den Austausch, hier muss ich ja erst "rec" aufrufen, dann "exchange" und am Schluss dann noch zurueckueberweisen, und das erzeugt dann doch wieder eine aehnliche Codemenge, wie wenn ich den Dreieckstausch jedesmal einzeln codiere.

      P.S. Und es geht doch in JS!

      Ja, aber leider nur auf Umwegen, das ist das Problem.

      Vielen Dank fuer Deine Muehe

      Bis danndann

      Michael N.

      1. Hallo Michael,

        Du gehst von der richtigen Praemisse aus. Ich _muss_ dabei aber gleichzeitig natuerlich auch noch den Code straff halten, das heisst in der aufrufenden Funktion genau einen Call fuer den Austausch, hier muss ich ja erst "rec" aufrufen, dann "exchange" und am Schluss dann noch zurueckueberweisen, und das erzeugt dann doch wieder eine aehnliche Codemenge, wie wenn ich den Dreieckstausch jedesmal einzeln codiere.

        Was hälts du von dieser Variante?

        function tausch(a,b)
        {
        tausche=new Array(2);
        tausche[0]=b;
        tausche[1]=a;
        return tausche;

        }
        function austauschen()
        {
        getauscht=tausch(2,5)
        alert(getauscht[0]);alert(getauscht[1]);
        }

        Viele Grüße

        Antje

        1. Hi hi!

          function tausch(a,b)
          {
          tausche=new Array(2);
          tausche[0]=b;
          tausche[1]=a;
          return tausche;

          }

          Gibt's natuerlich auch in kurz. ;-)
              function tausch(a, b) {
                  return [b, a];
              }

          function austauschen()
          {
          getauscht=tausch(2,5)
          alert(getauscht[0]);alert(getauscht[1]);
          }

          Vielleicht habe ich's falsch verstanden, aber wenn er nach dem Tausch statt auf a und b eben auf getauscht[0] und getauscht[1] zugreifen soll, koennte er ja auch gleich
              alert(b, a);
          schreiben.

          Mir ist noch etwas eingefallen, was vielleicht geht. Mal kurz hinueberlegt:

          function CreateSwapCode(a, b) {
                  return "var __swapcodetempvar = " + a + "; " + a + " = " + b + "; " + b + " = __swapcodetempvar;";
              }

          function FMAIN() {
                  var A = 10;
                  var B = 20;
                  alert("A=" + A );
                  alert("B=" + B );
                  eval(CreateSwapCode("A", "B"));
                  alert("A=" + A);
                  alert("B=" + B);
              }

          CreateSwapCode() erzeugt einen String mit JS-Code, der unten, da wo die Variablen leben, ausgefuehrt wird. Die Variablen muessen dabei als Strings uebergeben werden, damit die *Variablennamen*, nicht die *Werte*, in den Codestreifen eingebaut werden. Natuerlich kann man fuer die Funktion einen kuerzeren Namen waehlen, damit der Code kompakt bleibt. *g*

          Probier's mal aus, wuerde mich interessieren ob's geht.

          Ist natuerlich schwach, das JS keine echten Pointer kann. Damit ist es fuer mich nun aus dem Kreis der ernstzunehmenden Programmiersprachen herausgeflogen, wie vor langer Zeit schon Basic.

          Bye, Calocybe

          1. function tausch(a, b) {
                    return [b, a];

            function CreateSwapCode(a, b) {
                    return "var __swapcodetempvar = " + a + "; " + a + " = " + b + "; " + b + " = __swapcodetempvar;";
                }

            function FMAIN() {
                    var A = 10;
                    var B = 20;
                    alert("A=" + A );
                    alert("B=" + B );
                    eval(CreateSwapCode("A", "B"));
                    alert("A=" + A);
                    alert("B=" + B);
                }

            Probier's mal aus, wuerde mich interessieren ob's geht.

            Hallo Roland,

            es klappt :-)

            Viele Grüße

            Antje

  3. NB: Unter C geht das "Call by Reference" ueber Pointer, vielleicht gibt es sowas auch unter JavaScript als "undocumentated Feature".

    Wenn man die Sache mal ganz formalistisch angeht, dann kannst Du natürlich jederzeit Pointer über Arrays emulieren.
    Deine Variablen heißen dann eben nicht a und b, sondern sie heißen x[0] und x[1]. Wobei die Werte 0 und 1 die "Adressen" dieser Variablen sind, also ihre Pointer.
    Nicht, daß das Programm dadurch wesentlich besser lesbar werden würde ... aber es würde kaum länger werden.

    Was Du eigentlich brauchst, sind nicht Pointer, sondern eine Funktion, die einer Variablen den Pointer auf eine andere zuweisen kann. (Also den &-Operator aus C oder so ähnlich.)
    Wenn Du das hättest, dann könntest Du a und b als "alias-Namen" auf Deine Variablen benutzen und nur die "Referenzierung" würde dann den Wert des Pointers einer anderen Variablen zuweisen.

    (Was *ich* noch lieber hätte, wären keine Pointer, sondern wirklich VAR-Parameter. Ich will das nicht selbst programmieren müssen, wenn es die Sprache selbst auch kann.  Ich will nicht in Pointern denken, sondern in Variablen - und zwar in duplizierten und referenzierten. Ich liiiiebe Pascal ...)