Stefan Beck: Zugriff auf Member in verschachtelten Funktionen eines Objekts

Hallo zusammen!

Nach meiner langen, erfolglosen Suche hier und in anderen Foren - meine Stichworte function und OOP ist wohl etwas sehr häufig - wende ich mich nun aktiv an euch.

Ich habe mich in OOP-Javascript versucht und folgende Klasse geschrieben:

function ajaxQueue( size ) //CLASS
  {
    //MEMBER
    this.Size = size;
    var Count = 0;
    var Request = new Array( size );
    var ResponseHandler = new Array( size );
    var Event = new Array( size );
    var Handler = new Array( size );
    var EventName = 0;

//METHODEN
    this.GetEventName = function() { return EventName; };
    this.AddRequest = function( request, response_handler )
      {
        //Fuege einen neuen Request mit zugehoerigem Event und Handler ein
        if ( this.Size > Count )
        {
          Request[ Count ] = request;
          ResponseHandler[ Count ] = response_handler;
          Event[ Count ] = "AJAXready_" + Count;

(*)
          Handler[ Count ] = function( evt )
            {
              EventName = Event[ Count ];  //EventName = Event[] = Count = undefined
              alert( "EN: " + EventName );  //ebenso alle andere Member von ajaxQueue
              alert( "RQ: " + Request[ Count ] );
              makeRequest( Request[ Count ], ResponseHandler[ Count ] );
              document.body.removeEventListener( EventName, Handler[ Count ], false );
              EventName = 'AJAXready_' + Count + 1;
            }

document.body.addEventListener( Event[ Count ], Handler[ Count ], false );
          Count = Count + 1;
        }
      }

this.Start = function()
      {
        EventName = "AJAXready_0";
        this.Evnt = document.createEvent("Events");
        this.Evnt.initEvent( EventName, true, true);
        document.body.dispatchEvent( this.Evnt );
      };
  }

Soweit funktioniert auch vieles, jedoch ab der mit (*) markierten Stelle streikt. Wie zu sehen ist, wird die Funktion Handler[Count] innerhalb der Funktion AddRequest definiert, die wiederum in der Klasse eingebettet ist. Innerhalb der Funktion AddRequest kann ich auf die Member der Klasse ajaxQueue ohne weiteres zugreifen (z.B. this.size oder für private Member einfach nur Count).
Jedoch in der Funktion Handler[Count] bekomme ich jedesmal ein "undefined". Wenn ich innerhalb dieser Funktion auf einen öffentlichen Member wie this.Size zugreifen will, bekomme ich die Fehlermeldung "this.Size has no properties" (Firefox Fehlerconsole).

Da mir als Javascript-Anfänger langsam die Ideen ausgehen, wäre ich über jeden Vorschlag ziemlich happy.

Beste Grüße
   Stefan

  1. hi,

    //METHODEN
        this.GetEventName = function() { return EventName; };
        this.AddRequest = function( request, response_handler )

    Durch das this.{name} sind diese Methoden privilegierte Methoden.
    (Mittels var {name} = function() wären sie private Methoden.)

    Handler[ Count ] = function( evt )

    Aber was ist mit der hier?

    Kein this, kein var - weder privilegiert, noch privat. Public? Nee, auch nicht, da müsstest du über prototype gehen.

    Ich würde es an dieser Stelle also mal mit
    this.Handler[ Count ] = function( evt )
    versuchen - kann allerdings nicht versprechen, ob das das Gewünschte bewirkt, dafür ist mir der Fall bei meinem Javascript-OOP-Kenntnissgrad auch zu speziell.

    Generell halte ich mich an http://phrogz.net/JS/Classes/OOPinJS.html, wenn bei mir Unklarheiten bzgl. der verschiedenen "Arten" public, private, privileged von Methoden und Eigenschaften auftauchen.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. Handler[ Count ] = function( evt )

      Aber was ist mit der hier?

      Kein this, kein var - weder privilegiert, noch privat. Public? Nee, auch nicht, da müsstest du über prototype gehen.

      Naja, Handler ist privat, im Javascript'schen Sinne.
      Allerdings fehlt in der Funktion der Kontext

      Ich würde es an dieser Stelle also mal mit
      this.Handler[ Count ] = function( evt )
      versuchen - kann allerdings nicht versprechen, ob das das Gewünschte bewirkt, dafür ist mir der Fall bei meinem Javascript-OOP-Kenntnissgrad auch zu speziell.

      oder var self = this und in der Funktion mit self arbeiten.

      Ich hab aber auch Schwierigkeiten exakt nachzuvollziehen, was der OP macht, ohne ein konkretes Beispiel.

      Struppi.

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

        ich hab den Fehler gefunden. Und zwar darf die Funktion Handler[Count] nicht mit

        Handler[ Count ] = function( ... ) { ... }

        erzeugt werden, sondern sie muss mit

        Handler[ Count ] = new function( ... ) { ... }

        erzeugt werden, da sie ja in einem Array untergebracht ist (soweit meine Theorie). Ich glaube den Wald vor lauter Bäumen nich mehr gesehen zu haben ;-)

        Vielen Dank für all die schnellen Antworten!

        Beste Grüße
          Stefan

        1. Hallo nochmal!

          ich hab den Fehler gefunden. Und zwar darf die Funktion Handler[Count] nicht mit

          Handler[ Count ] = function( ... ) { ... }

          erzeugt werden, sondern sie muss mit

          Handler[ Count ] = new function( ... ) { ... }

          nein, das sind zwei völlig unterschiedliche Dinge, probier es aus:

          var t1 = function() { alert( 't1:' + this ); };  
          var t2 = new function() { alert( 't2:' + this ); };  
            
          t1();  
          t2();  
          
          

          Erst erscheint 't2: Object', weil new die Funktion quasi aufruft, dann 't1: window', da this hier gleich window ist und eine Fehlermeldung "t2() is not a function", weil es ein Objekt ist.

          Struppi.

          --
          Javascript ist toll (Perl auch!)
          1. Ok, .... ich denke den Unterschied habe ich verstanden. Wie du sagtest: Holzweg. Vielen Dank für diese Zurechtweisung. Ohne erneut an Prinzipien von JS anecken zu wollen:

            Mit new function() erzeuge ich ein Objekt einer Funktion. Es wird beim Erzeugen "aufgerufen". Direkt aufrufen kann ich es aber nicht, soweit richtig? Insofern muss ich dies komplett verwerfen. Also zurück zu meinem ursprüunglichen Problem.

            Mein anfänglicher Ansatz, in meinem ersten Post, zeigt noch, dass ich auschließlich mit function() ohne new arbeite. So habe ichs bisher immer gehalten mit Methoden einer Klasse und war erstaunt, als ich dann jene eine Grenze stieß. Ich versuche nochmal zu beschreiben, was für ein Problem in meinem urprüuinglichen Code steckt:

            Innerhalb einer mit function erzeugten Methode A der Klasse erzeuge ich mit function eine andere Methode B der Klasse. Methode A ist in einer privilegierten Membervariable untergebracht, Methode B in einem privaten Array (quasi "von Funktionen").
            Innerhalb der Methode A kann ich auf alle Member der Klasse zugreifen. Innerhalb von Methode B geht dies nicht mehr. Irgendwie geht der Kontext verloren.

            Methode A ist bei mir this.AddRequest( ... ); Methode B ist Handler Count ;

            Zu eurem bisherigen Vorschlag dazu:
            Mit var self = this innerhalb von Handler[Count] zu arbeiten kann ich nicht nachvollziehen. Ich habe es versucht, ohne Erfolg. Habe ich das denn richtig verstanden: Diese Deklaration muss ja zwangsläufig außerhalb von Handler[ Count ] geschehen. Da ich von innen dann aber keinen Zugriff auf die Membervariable self habe, ist es Witzllos. Außer ich definiere var self im globalen Scope. Wäre aber sehr unschön und ich müsste alle Member der Klasse ajaxQueue privilegieren.

            Wie dem auch sei, jedenfalls vielen herzlichen Dank für die bisherigen Bemühungen!

            Stefan

            1. Mit new function() erzeuge ich ein Objekt einer Funktion. Es wird beim Erzeugen "aufgerufen". Direkt aufrufen kann ich es aber nicht, soweit richtig? Insofern muss ich dies komplett verwerfen. Also zurück zu meinem ursprüunglichen Problem.

              Du musst dir das OO Konzept von JS mal anschauen:

              function Obj() {... }

              new Obj();

              Du hast also eine Funktion, die quasi der Konstruktor ist und mit

              new function() { .... }

              ist es einfach eine anonyme Funktion. Das ist aber nicht unbedingt sinnvoll, da du so nur ein Objekt erzeugen kannst.

              Innerhalb einer mit function erzeugten Methode A der Klasse erzeuge ich mit function eine andere Methode B der Klasse. Methode A ist in einer privilegierten Membervariable untergebracht, Methode B in einem privaten Array (quasi "von Funktionen").
              Innerhalb der Methode A kann ich auf alle Member der Klasse zugreifen. Innerhalb von Methode B geht dies nicht mehr. Irgendwie geht der Kontext verloren.

              genau, und um den behalten zu können musst du in dem Fall auf einen Trick zurückgreifen:

              var self = this;
              ....

              danach kannst du in deinen privaten Methoden über self auf das aktuelle Objekt zugreifen.

              Zu eurem bisherigen Vorschlag dazu:
              Mit var self = this innerhalb von Handler[Count] zu arbeiten kann ich nicht nachvollziehen. ....

              nicht innerhalb von Handler[] sondern innerhalb von addRequest() oder im Konstruktor.

              ...Ich habe es versucht, ohne Erfolg. Habe ich das denn richtig verstanden: Diese Deklaration muss ja zwangsläufig außerhalb von Handler[ Count ] geschehen. Da ich von innen dann aber keinen Zugriff auf die Membervariable self habe, ist es Witzllos.

              Wieso nicht, self ist quasi eine private Variabel und du kannst innerhalb der privaten Funktion auf self zugreifen.

              Ich hab mir deinen Code nochmal angeschaut, da sind noch mehr Sachen, die so nicht funktionieren. Die Funktion document.createEvent(); war mir bisher unbekannt, mir ist aber nicht ganz klar warum du sie brauchst. Auch das was du bei addEventListener einträgst ist kein gültiger Event, soweit ich das sehe, der irgendwann gefeuert wird.

              Struppi.

              --
              Javascript ist toll (Perl auch!)
              1. Ok, Schande über mich, ich habe den Fehler gefunden. Bin mit meinem Array-Index an bestimmter Stelle schlichtweg über die Grenzen des Arrays gegangen. So konnte es keine neue Funktion Handler[ Count ] mehr geben.
                Nun bin ich allerdings durch damit, und es funktioniert. Vielen Dank für die tatkräftige Unterstützung.

                Nun mal zum Kontext: Ich bin gerade dabei eine Art Queue für Ajax-Requests zu schreiben. Ich setzte mehrere Anfragen in die Queue, jeweils mit zwei Parametern definiert (das könnte z.B. ein SQL-Statement sein), und wenn ich fertig bin, lasse ich die Anfragen der Reihen nach abarbeiten. Serialisieren. Dabei benutze ich aus bestimmten Gründen nur ein HTTPRequest-Objekt.
                Das ganze ist allerdings in ein mittlereweile recht komplexes Framework eingebettet. Warum ich Events benötige? Da ich nur ein HTTPRequest-Objekt benutze, kann ich nur eine einzige Anfrage senden und empfangen. Da Ajax naturgemäß aber asynchron zu JS und Browser läuft, lasse ich mir das Eintreffen einer Antwort auf mein Request per Event anzeigen.
                Die Queue an und für sich ist bisher nur mit Firefox erfolgreich getestet. createEvent, dispatchEvent und addEventListener bzw removeEventListener sind im IE wieder etwas anders von der Parametrierung. Unterstützung für weitere Browser ist in diesem Fall nicht relevant, wenn auch interessant.

                Nun, wie dem auch sei, hier der Code, wie's bei mir funktioniert (FF2.0):
                [Code]
                  function ajaxQueue( size ) //CLASS
                  {
                    //MEMBER
                    this.Size = size;
                    this.Evnt = 0;
                    var Count = 0;
                    var Request = new Array( size );
                    var ResponseHandler = new Array( size );
                    var Event = new Array( size );
                    var Handler = new Array( size );
                    var Index = 0;
                    var EventName = 0;

                //METHODEN
                    this.GetEventName = function() { return EventName; }
                    this.AddRequest = function( request, response_handler )
                      {
                        //Fuege einen neuen Request mit zugehoerigem Event und Handler ein
                        if ( this.Size > Count )
                        {
                          Request[ Count ] = request;
                          ResponseHandler[ Count ] = response_handler;
                          Event[ Count ] = "AJAXready_" + Count;
                          Handler[ Count ] = function( event )
                            {
                              EventName = Event[ Index ];
                              makeRequest( Request[ Index ], ResponseHandler[ Index ] );
                              document.body.removeEventListener( EventName, Handler[ Index ], false );

                if ( Index < Count - 1) Index++; else Index = 0;
                              EventName = 'AJAXready_' + Index;
                            }
                          document.body.addEventListener( Event[ Count ], Handler[ Count ], false );
                          Count++;
                        }
                      }

                this.Start = function()
                      {
                        EventName = "AJAXready_0";
                        this.Evnt = document.createEvent("Events");
                        this.Evnt.initEvent( EventName, true, true);
                        document.body.dispatchEvent( this.Evnt );
                      };
                  }

                [/Code]

                Aufruf der Queue wie folgt:

                [Code]
                    ajaxAufQueue = new ajaxQueue( 4 );
                    ajaxAufQueue.AddRequest( SQLStatement, "ajaxResponse_TableMain" );
                    ...
                    ajaxAufQueue.Start();
                [/Code]

                Vllt gibts dann bald was allgemein-verträgliches ;-)

                Nochmals vielen Dank für die Hilfe! Hat mich vom Verständnis her sehr viel weiter gebracht, denke ich.

                Bestes Grüßle,
                  Stefan

    2. Hallo, danke für die Antwort.

      Leider trift das ganze mein Problem nicht ganz.

      Generell halte ich mich an http://phrogz.net/JS/Classes/OOPinJS.html, wenn bei mir Unklarheiten bzgl. der verschiedenen "Arten" public, private, privileged von Methoden und Eigenschaften auftauchen.

      Danke für den Link, ist eine schöne Übersicht, allerdings soweit ichs beurteilen kann nicht relevant für mein Problem.

      Durch das this.{name} sind diese Methoden privilegierte Methoden.
      (Mittels var {name} = function() wären sie private Methoden.)

      Handler[ Count ] = function( evt )

      Aber was ist mit der hier?

      Diese Funktion wurde bereits weiter oben innerhalb eines privaten Array definiert:

      var Handler = new Array( size );

      Die Funktion Handler[ Count ] soll nicht von außerhalb gerufen werden können, sondern nur von ajaxQueue selbst. Der Aufruf an und für sich funktioniert auch. Die privaten und privilegierten Methoden sind gewollt so gesetzt. Ich habe allerdings auch schon einmal alles privilegiert deklariert (man experimentiert schon), ohne Effekt.

      Nochmal das Problem, so wie es auftritt:
      Mittels AddRequest werden Daten in das Objekt ajaxQueue eingefügt. Dabei werden jedesmal verschiedene Funktionen Handler[ Count ] mit einem Datensatz verknüpft.
      Die Funktion Handler[ Count ] wird dann als Event-Handler aufgerufen. Bis zu diesem Punkt funktioniert alles wunderbar, die Daten werden korrekt eingefügt, die Handler werden korrekt gesetzt, und sie reagieren auf das entwprechende Event.
      Allerdings reagieren sie falsch. Wie bereits erwähnt gehört jeder Handler[ Count ] zu anderen Membern von ajaxRequest, z.B. Request[ Count ]. Innerhalb eines Handler[ Count ] kann ich allerdings nicht mehr auf diese anderen Member von ajaxRequest zugreifen.
      Wenn ich so z.B. mittels alert( EventName ); etwas anzeigen lasse, wird die Zugehörigkeit von Handler[ Count ] zu ajaxRequest nicht erkannt, und es wird im globalen Scope eine neue Variable EventName angelegt. Wenn ich die Zugehörigkeit explizit kennzeichnen will, also alert( ajaxQueue.EventName ); anfordere, bekomme ich wiederum den Fehler, "... has no properties". Blöd.

      Ich würde es an dieser Stelle also mal mit
      this.Handler[ Count ] = function( evt )

      Nun, gut dass du nichts verprochen hast ;-) aber vielen Dank!

      Normalerweise sollte es doch vereinfacht so funktionieren.... nochmal vereinfacht woran es hapert:

      function Object()
      {
        var data=5;
        this.moredata=6;
        var f1;
        var f2 = new function()
          {
            f1 = new function()           //f1 dynamisch erzeugen
              {
                alert( data );            //gibt "undefined"
                alert( this.moredata );   //erzeugt Fehler "this.moredata has no properties"
              }
            f1();                         //f1 ausführen
          }
      }

      Any ideas? Vermutlich stell ich mich grad äußerst dämlich an, aber ich denke nach zwei Tagen an diesem Problem fehlt mir langsam die Objektivität.

      Beste Grüße
        Stefan

      1. Normalerweise sollte es doch vereinfacht so funktionieren.... nochmal vereinfacht woran es hapert:

        nein, das funktioniert nicht.

        function Object()

        Das Objekt existiert schon, ich glaub nicht das man das überschreiben kann.

        {
          var data=5;
          this.moredata=6;
          var f1;
          var f2 = new function()

        Wieso new?
        Du erzeugst hier ein neues Objekt, das ist etwas anderes, als eine anonyme Funktion.

        {
              f1 = new function()           //f1 dynamisch erzeugen

        Wenn du eine Funktion dynamisch erzeugen willst, meinst du evtl. new Function() (JS ist case sensitive).

        {
                  alert( data );            //gibt "undefined"

        Dann machst du schon etwas bei der Deklaration falsch, hier wird bei mir 5 ausgegeben.

        alert( this.moredata );   //erzeugt Fehler "this.moredata has no properties"

        und hier undefined.

        Any ideas? Vermutlich stell ich mich grad äußerst dämlich an, aber ich denke nach zwei Tagen an diesem Problem fehlt mir langsam die Objektivität.

        Du solltest dir noch mal die Seite die wahsaga verlinkt hat anschauen, dort wird beschrieben wie es richtig geht, bei dir ist der ansatz nicht korrekt. OOP in JS ist etwas seltsam und nciht ganz einfach.

        Struppi.

        --
        Javascript ist toll (Perl auch!)
        1. Ok, zugegeben, der Name Object für mein on-the-fly-getipptes Beispiel war blöd. Und es funktioniert natürlich auch so, wie du's beschrieben hast. mit den Kommentaren wollte ich nur verdeutlichen, was in meinem eigentlichen Code nicht funktioniert.

          Wenn du eine Funktion dynamisch erzeugen willst, meinst du evtl. new Function() (JS ist case sensitive).

          Nein, das meinte ich nicht, aber auch das habe ich bereits ausprobiert, ohne Erfolg. Dass ich hier new function geschrieben habe war eher Resultat meiner derzeitigen Verwirrung als gewollte Intention.

          Du solltest dir noch mal die Seite die wahsaga verlinkt hat anschauen, dort wird beschrieben wie es richtig geht, bei dir ist der ansatz nicht korrekt. OOP in JS ist etwas seltsam und nicht ganz einfach.

          Das werd ich auf jeden Fall nochmal machen. Wie ich bereits geschrieben hab, hat sich der Erfolg nun eingestellt indem ich eben dieses "Handler[ Count ] = new function()" verwendet habe, eher zufällig als gewollt. Merkwürdigerweise funktioniert es (zumindest im Firefox). Es ist mir jedenfalls klar, dass ich mir new eine Instanz einer "Klasse", also ein Objekt erzeuge. Warum das auch mit function (nicht aber mit Function) funktioniert werd ich mir jetzt mal ansehen.
          Aber richtig: OOP und JS sind wirklich merkwürdig für jemanden der aus der C++ Welt kommt.

          Stefan

          1. Wenn du eine Funktion dynamisch erzeugen willst, meinst du evtl. new Function() (JS ist case sensitive).

            Nein, das meinte ich nicht, aber auch das habe ich bereits ausprobiert, ohne Erfolg. Dass ich hier new function geschrieben habe war eher Resultat meiner derzeitigen Verwirrung als gewollte Intention.

            und ist auch vermutlich falsch. mit new function() erzeugst du ein neues Objekt und function() erzeugt eine anonyme Funktion, was du konkret willst ist nicht so klar, würde aber eher auf das 2. tippen.

            Du solltest dir noch mal die Seite die wahsaga verlinkt hat anschauen, dort wird beschrieben wie es richtig geht, bei dir ist der ansatz nicht korrekt. OOP in JS ist etwas seltsam und nicht ganz einfach.

            Das werd ich auf jeden Fall nochmal machen. Wie ich bereits geschrieben hab, hat sich der Erfolg nun eingestellt indem ich eben dieses "Handler[ Count ] = new function()" verwendet habe, eher zufällig als gewollt. Merkwürdigerweise funktioniert es (zumindest im Firefox). Es ist mir jedenfalls klar, dass ich mir new eine Instanz einer "Klasse", also ein Objekt erzeuge. Warum das auch mit function (nicht aber mit Function) funktioniert werd ich mir jetzt mal ansehen.

            Bei mir funktioniert es mit deinem Testcode gerade nicht mit new function(), da f1() keine Funktion, sondern ein Objekt ist und daher f1() nicht funktioniert.
            Ich bin sicher, dass du damit auf dem Holzweg bist.

            Struppi.

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

    generell solltest du dir http://aktuell.de.selfhtml.org/artikel/javascript/organisation/ durchlesen - auch wenn es da nicht um künstliche Events geht.

    Das hier sollte dir klar sein:

    function Konstruktor () {  
     alert("Zugriff auf das neu erschaffene Objekt: " + this);  
     this.öffentlicheMethode = function () {  
      alert("Zugriff auf das neu erschaffene Objekt: " + this);  
     };  
    }  
    var meinObjekt = new Konstruktor;  
    meinObjekt.öffentlicheMethode();
    

    In Objektmethoden zeigt this auf die jeweilige Instanz. Man sagt, die Objektmethoden werden im Kontext der Instanz ausgeführt - das heißt eben, das this darauf zeigt. Nur darin zeigt sich die Zugehörigkeit einer Funktion zu einem Objekt; das macht die Methode zur Methode.

    Bei Event-Handlern kommt jetzt eine andere Sache hinein: In Handlerfunktionen zeigt »this« auf das Objekt, bei dem der Event passierte, also dessen Handler gerade ausgelöst wurde.

    document.body.addEventListener("click", handler, false);  
    function handler () {  
     alert("Kontext: " + this);  
    }
    

    Hier ist this gleich das DOM-Knotenobjekt (in dem Fall Elementobjekt), bei dem der click-Event passierte.

    Wenn du nun mit synthetischen Events arbeitest, passiert eigentlich genau dasselbe: this zeigt in der Handlerfunktion auf das DOM-Knotenobjekt bzw. ein sonstiges Objekt wie z.B. window, bei dem du das Ereignis mit dispatch eingeleitet hast.

    window.onload = start;  
    function überwache (e) {  
     alert(e.target + "\n" + e.currentTarget + "\n" + this);  
    }  
    function start () {  
     document.body.addEventListener("MeinEreignis", überwache, true);  
     var ev = document.createEvent("Events");  
     ev.initEvent("MeinEreignis", true, true);  
     document.body.dispatchEvent(ev);  
    }
    

    target, currentTarget und this sind hier identisch. (this ist immer identisch mit currentTarget, wegen aufsteigender Events nicht notwendigerweise identisch mit target. Hier wird der Event aber genau dort behandelt, wo er auch ursprünglich passiert - bei document.body.)

    Soweit klar - das Problem entsteht jetzt bei der verschachtelten Notierung von Objektmethoden und Event-Handler-Funktionen.

    Mal die obigen Beispiele kombiniert:

    function Konstruktor () {  
     this.starteÜberwachung = function () {  
      var überwache = function (e) {  
       alert(e.target + "\n" + e.currentTarget + "\n" + this);  
      };  
      document.body.addEventListener("MeinEreignis", überwache, true);  
     };  
     this.löseAus = function () {  
      var ev = document.createEvent("Events");  
      ev.initEvent("MeinEreignis", true, true);  
      document.body.dispatchEvent(ev);  
     };  
    }  
      
    window.onload = start;  
      
    function start () {  
     var meinObjekt = new Konstruktor;  
     meinObjekt.starteÜberwachung();  
     meinObjekt.löseAus();  
    };
    

    Jetzt musst du dir nur klar darüber werden, in welchem Kontext die Funktionen jeweils ausgeführt werden.

    • starteÜberwachung wird im Kontext von meinObjekt ausgeführt.
    • überwache wird zwar in einer Methode von meinObjekt notiert, wird aber dann als Handlerfunktion an document.body gebunden. In dessen Kontext wird diese Funktion schließlich auch ausgeführt! Also zeigt this darin nicht auf meinObjekt, sondern document.body.
    • löseAus wird wieder normal im Kontext von meinObjekt ausgeführt.

    Wie kommt man in überwache nun elegant an die Instanz heran (also meinObjekt)? Da gibt es verschiedene Möglichkeiten (siehe Artikel), von denen du eine auch letztlich selbst gefunden hast, wenn womöglich auch unabsichtlich: nämlich Closures. Die wurden die auch empfohlen, als von »var self = this« die Rede war.

    Closures sind eine Eigenart, die bei verschachtelten Funktionen auftritt: Die lokalen Variablen der äußeren Funktion sind auch in der inneren verfügbar, selbst wenn diese zu einer anderen Zeit in einem anderen Kontext auseführt wird.

    function Konstruktor () {  
     var self = this;  
     this.eigenschaft = "bla";  
     this.starteÜberwachung = function () {  
      // Funktion in Funktion: Closure, die self einschließt  
      var überwache = function (e) {  
       // Funktion in Funktion in Funktion: Closure, die self einschließt  
       alert(self + " versus " + this);  
       alert(this.eigenschaft);  
      };  
    ...
    

    So würde ich es lösen - alle Variablen als Objekteigenschaften lösen, dann *eine* Variable (nämlich self) weitervererben, die auf die Instanz verweist. Darüber dann auf die Objekteigenschaften zugreifen. Du hast dich dazu entschlossen, viele Variablen durch Closures weiterzureichen (Count, Request, ResponseHandler, Event, Handler, Index).

    Mathias

    1. Hallo,

      generell solltest du dir http://aktuell.de.selfhtml.org/artikel/javascript/organisation/ durchlesen -

      Weil's gerade dazu passt, der Link zu "Object Literal – Warum neuere Skripte anders aussehen)" in http://aktuell.de.selfhtml.org/artikel/javascript/organisation/#object-literale hat sich auf http://grochtdreis.de/altesweblog/index.php?id=P953 geändert (aber wenn ich das im Bolg änderte stehe ich dann als "Autor" drinn).

      Grüße
      Thomas

      1. Hallo,

        Weil's gerade dazu passt, der Link zu "Object Literal – Warum neuere Skripte anders aussehen)" in http://aktuell.de.selfhtml.org/artikel/javascript/organisation/#object-literale hat sich auf http://grochtdreis.de/altesweblog/index.php?id=P953 geändert (aber wenn ich das im Bolg änderte stehe ich dann als "Autor" drinn).

        Danke, ich habs geändert.
        (Die Datei liegt ganz normal als schnöde .html im aktuell-SVN, mit dem Blog hat das also nichts zu tun. Oder kommt der Link nochmal in einem Blogartikel vor? Hier zumindest nicht...)

        Mathias

        1. Hallo,

          Danke, ich habs geändert.
          (Die Datei liegt ganz normal als schnöde .html im aktuell-SVN, mit dem Blog hat das also nichts zu tun. Oder kommt der Link nochmal in einem Blogartikel vor? Hier zumindest nicht...)

          Oh, da bin ich wohl beim Lesen durcheiander gekommen.

          Grüße
          Thomas