Jeena Paradies: Clousures verlieren Variable

Hallo,

Ich scheine JavaScript völlig verlernt zu haben, denn ich bekomme es einfach nicht hin dass es das tut was ich will. Ich versuche es mal zu beschreiben.

Ich habe ein großes Objekt. Dieses Objekt benötigt Daten die nachgeladen werden müssen. Das erledigt die Funktion Request. Es soll dann eine Methode des Objekts (myCallback) (bzw. genau dieser Instanz) mit den geholten Daten aufgerufen werden.

  
    function obj() {  
  
        this.myCallback = function(req) {  
            alert(req);  
        }  
  
        self = this;  
  
        Request( function() { self.myCallback() } );  
    }  
  
    function Request(callback) {  
        // simuliert einen Ajax Request  
  
        window.setTimeout( function() { callback('ich bin callback') }, 1000);  
    }  
  
    foo();  

Das produziert mit aber ein Alert mit undefined anstatt 'ich bin callback'. Was mache ich falsch?

Grüße
Jeena Paradies

--
Freie Resourcen - Arbeit gesucht | Jlog | Gourmetica Mentiri
  1. Hallo,

    Ich habe ein großes Objekt. Dieses Objekt benötigt Daten die nachgeladen werden müssen. Das erledigt die Funktion Request. Es soll dann eine Methode des Objekts (myCallback) (bzw. genau dieser Instanz) mit den geholten Daten aufgerufen werden.

    function obj() {

    this.myCallback = function(req) {
                alert(req);
            }

    //self = this;

    ^window.self = this?
               var self = this;

    Request( function() { self.myCallback() } );

    ^hier wird Request mit einem Parameter aufgerufen, der eine anonyme Funktion _ohne_ Parameter darstellt, welche self.myCallback() _ohne_ Parameter aufruft.

    }

    function Request(callback) {

    ^callback ist hier, nach dem Erzeugen von obj(), function() { self.myCallback() }, also eine anonyme Funktion _ohne_ Parameter.

    window.setTimeout( function() { callback('ich bin callback') }, 1000);

    ^hier wird callback aber mit Parameter aufgerufen, der geht allerdings ins Nirvana, da callback wiederum .myCallback() _ohne_ Parameter aufruft.

    }

    foo();

    ^?
           var myObj = new obj();

    Das produziert mit aber ein Alert mit undefined anstatt 'ich bin callback'.

    Klar, myObj.myCallback().

    viele Grüße

    Axel

    1. Hallo,

      Request( function() { self.myCallback() } );
                 ^hier wird Request mit einem Parameter aufgerufen, der eine anonyme Funktion _ohne_ Parameter darstellt, welche self.myCallback() _ohne_ Parameter aufruft.

      Jo nach langem hinsehen habe ich das dann auch von selbst eingesehen ;-) Manchmal ist man ja doch etwas Logik-blind.

      foo();
             ^?
             var myObj = new obj();

      Jo fooÄ(); war hier fälschlicherweise beim Kopieren übriggeblieben. Aber das mit dem new obj(); ist ja nicht wirklich zwingend notwendig, oder? Also wenn ich ansonsten nichts damit machen will.

      Grüße
      Jeena Paradies

      --
      Freie Resourcen - Arbeit gesucht | Jlog | Gourmetica Mentiri
      1. foo();
               ^?
               var myObj = new obj();

        Jo fooÄ(); war hier fälschlicherweise beim Kopieren übriggeblieben. Aber das mit dem new obj(); ist ja nicht wirklich zwingend notwendig, oder? Also wenn ich ansonsten nichts damit machen will.

        Naja, dann brauchst du auch kein Objekt, wenn du kein Objekt benutzen willst.

        Aber selbst wenn, du kannst das ganze gar nicht als Objekte nutzen. Da du immer nur ein Objekt als Referenz auf den callback übergibst nämlich die globale Variabel self, das heißt du kannst einfach Funktionen verwenden und benötigst gar kein Objekt.

        Struppi.

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

          Aber selbst wenn, du kannst das ganze gar nicht als Objekte nutzen. Da du immer nur ein Objekt als Referenz auf den callback übergibst nämlich die globale Variabel self, das heißt du kannst einfach Funktionen verwenden und benötigst gar kein Objekt.

          Ja, ne, das mit dem globalen self war ein Fehler, das sollte schon lokal sein, da das eigentliche Script etwas komplizierter aufgebaut ist, aber du hast schon recht, ich glaube ich verstehe was du damit sagen willst.

          Grüße
          Jeena Paradies

          --
          Freie Resourcen - Arbeit gesucht | Jlog | Gourmetica Mentiri
          1. Hallo,

            Ja, ne, das mit dem globalen self war ein Fehler, das sollte schon lokal sein,

            Wobei ich dann nicht verstehe, warum Du einerseits myCallback(req) als Public-Methode des Objektes deklarierst, dann aber das Objekt in eine private Variable self steckst, um die Methode myCallback(req) dieses privaten Objektes aufzurufen.

            Kann es sein, dass Du eher soetwas willst:

              
                function obj() {  
              
                    var myCallback = function(req) {  
                        alert(req);  
                    }  
              
                    Request( function(e) { myCallback(e) } );  
                }  
              
                function Request(callback) {  
                    // simuliert einen Ajax Request  
              
                    window.setTimeout( function() { callback('ich bin callback') }, 1000);  
                }  
              
                var myObj = new obj();  
              
                //myObj.myCallback("Hallo Welt"); //produziert einen Fehler  
            
            

            viele Grüße

            Axel

            1. Hallo,

              Wobei ich dann nicht verstehe, warum Du einerseits myCallback(req) als Public-Methode des Objektes deklarierst, dann aber das Objekt in eine private Variable self steckst, um die Methode myCallback(req) dieses privaten Objektes aufzurufen.

              Huch, hm keine Ahnung, wohl weil ich mit JS gerade irgendwie nicht so recht zurechtkomme. Verstehe ich das richtig, dass die Syntas var f = function() { } einfach nur bedeutet, dass das eine private Methode ist und this.f = function() { } dass es eine Public-Methode? Das hat mich nämlich bisher schon immer verwirrt, würde aber vieles Erklären was ich bisher nicht verstand im Umgang mit JavaScript.

              Kann es sein, dass Du eher soetwas willst:

              function obj() {

              var myCallback = function(req) {
                          alert(req);
                      }

              Request( function(e) { myCallback(e) } );
                  }

              function Request(callback) {
                      // simuliert einen Ajax Request

              window.setTimeout( function() { callback('ich bin callback') }, 1000);
                  }

              var myObj = new obj();

              //myObj.myCallback("Hallo Welt"); //produziert einen Fehler

                
              Wenn myCallback dann dennoch wieder andere Methoden dieser Instanz aufrufen kann dann wohl ja.  
                
              Grüße  
              Jeena Paradies
              
              -- 
              [Freie Resourcen](http://jeenaparadies.net/weblog/2006/may/ich-habe-freie-resourcen) - Arbeit gesucht | [Jlog](http://jeenaparadies.net/webdesign/jlog/) | [Gourmetica Mentiri](http://jeenaparadies.net/gourmetica-mentiri/)
              
              1. Huch, hm keine Ahnung, wohl weil ich mit JS gerade irgendwie nicht so recht zurechtkomme. Verstehe ich das richtig, dass die Syntas var f = function() { } einfach nur bedeutet, dass das eine private Methode ist und this.f = function() { } dass es eine Public-Methode? Das hat mich nämlich bisher schon immer verwirrt, würde aber vieles Erklären was ich bisher nicht verstand im Umgang mit JavaScript.

                  
                // Es ist üblich die Namen von Objekte/Klassen mit Großbuchstaben zu beginnen  
                function Obj()  
                {  
                    var x = 0; // private Variabel  
                  
                    // private Funktionen  
                    function private() {} ;  
                    // oder  
                    var private = function() {};  
                  
                    // Privilegiert Methode kann auf private Funktionen und Variabeln zugreifen  
                     this.funktion = function() {};  
                }  
                // Public  
                Obj.prototype.funktion = function() {};  
                
                

                Es ist allerdings noch ein bisschen komplizierter, wenn du Vererben willst.

                Wenn myCallback dann dennoch wieder andere Methoden dieser Instanz aufrufen kann dann wohl ja.

                Nein, dazu musst du wieder eine private variabel var self = this; erzuegen.

                Struppi.

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

                Wobei ich dann nicht verstehe, warum Du einerseits myCallback(req) als Public-Methode des Objektes deklarierst, dann aber das Objekt in eine private Variable self steckst, um die Methode myCallback(req) dieses privaten Objektes aufzurufen.

                Huch, hm keine Ahnung, wohl weil ich mit JS gerade irgendwie nicht so recht zurechtkomme. Verstehe ich das richtig, dass die Syntas var f = function() { } einfach nur bedeutet, dass das eine private Methode ist

                Ja. Wobei man dann auch einfach innerhalb der äußeren Funktion (der Pseudo-Class) wieder

                function f() { }

                schreiben kann.

                und this.f = function() { } dass es eine Public-Methode?

                Ja, allerdings mit privilegiertem Zugriff auch auf die privaten Methoden und Eigenschaften des Objektes.

                Das hat mich nämlich bisher schon immer verwirrt, würde aber vieles Erklären was ich bisher nicht verstand im Umgang mit JavaScript.

                JavaScript is the world's most misunderstood programming language. Douglas Crockford

                Wenn myCallback dann dennoch wieder andere Methoden dieser Instanz aufrufen kann dann wohl ja.

                Kann es:

                  
                    function obj() {  
                  
                        var self = this;  
                  
                        var myCallback = function(req) {  
                            self.publicMethod(req);  
                            privateMethod(req);  
                        }  
                  
                        this.publicMethod = function(e) {  
                            alert("from public method: " + e)  
                        }  
                  
                        function privateMethod(e) {  
                            alert("from private method: " + e)  
                        }  
                  
                        Request( function(e) { myCallback(e) } );  
                    }  
                  
                    function Request(callback) {  
                        // simuliert einen Ajax Request  
                  
                        window.setTimeout( function() { callback('ich bin callback') }, 1000);  
                    }  
                  
                    var myObj = new obj();  
                  
                    myObj.publicMethod("Hallo Welt");  
                
                

                viele Grüße

                Axel

                1. hi,

                  JavaScript is the world's most misunderstood programming language. Douglas Crockford

                  Bah, ist die Seite hässlich und altbacken :-)

                  Da gefällt mir die folgende doch besser - insbesondere der Kürzüberblick zu Beginn, falls man's hin und wieder in den Anfängen noch vergisst:
                  http://phrogz.net/JS/Classes/OOPinJS.html

                  gruß,
                  wahsaga

                  --
                  /voodoo.css:
                  #GeorgeWBush { position:absolute; bottom:-6ft; }
                  1. Hallo,

                    JavaScript is the world's most misunderstood programming language. Douglas Crockford

                    Bah, ist die Seite hässlich und altbacken :-)

                    Da kannst Du mal sehen, wie lange JavaScript schon missverstanden wird ;-)

                    viele Grüße

                    Axel

  2. Hallo,

    So, man muss den Code nur einfach lange genug anstarren, dann kommt man schon irgendwann auf die Lösung von selbst. Na wenigstens bin ich nicht kurz nach dem Abschicken draufgekommen und ihr hattet Zeit ein bischen darüber zu grübeln. Hier nun die Auflösung (beachtet das "e"):

    Request( function(e) { self.myCallback(e) } );

    Grüße
    Jeena Paradies

    --
    Freie Resourcen - Arbeit gesucht | Jlog | Gourmetica Mentiri