BBKing: OOP: Event an Member-Variable hängen?

Hallo Forum,

ich hätte auch 'mal eine Frage, da ich gerade an einem AJAX-Script arbeite und derzeit anstehe:
Gibt es eine Möglichkeit, einer Member-Varibale einer JS-Klasse ein Event anzuhängen?

Es geht um folgendes (ein wenig aufwendig zum Verstehen):
Objekt liest über AJAX Werte von einer Hardware. Die Kleinste "lesbare" Einheit sind sagen wir 2 Bytes.
Da ich aber teilweise einzelne Bits benötige, lese ich nun die 16 Bits und verunde sie mit der jeweiligen Stelle (zb benötige ich den Wert vom 3. Eingangskanal, dann mache ich: Wert & 2^2 -> liefert 0 oder 1 -> damit weiß ich, ob der Kanal gesetzt ist oder nicht)

Soweit kein Problem, ich möchte aber den HTTP-Request nicht 16x ausführen um zu erfahren, ob die einzelnen Kanäle gesetzt sind sondern möchte einmal "blockweise" den Wert lesen und wenn der neue Wert da ist, die anderen Objekte über das Update in Kenntnis setzen und in einer Member-Funktion die Verundung durchführen. D.h. ich möchte im Originalobjekt die Eingangsvariable von der Hardware setzen und in den anderen Objekten auf diese Variable referenzieren. Wenn sie geändert wird, soll in den anderen Objekten die Funktion zum Prüfen der Bitstelle ausgeführt werden (sprich an die Eingangsvariable ein onchange-Event hängen).

:D

Also kurz und bündig: kann man an eine Member-Variable ein onchange Event hängen, sodass eine Funktion ausgeführt wird, wenn sich die Variable ändert. Ich vermute jedoch, die Antwort ist nein.

Danke im Voraus!

  1. Hallo,

    Ich vermute jedoch, die Antwort ist nein.

    Ich vermute dagegen, die Antwort ist ja. Nicht ganz trivial, aber das sollte gehen. Leider verstehe ich deine deine Beschreibung nur ganz grob:

    ich möchte aber den HTTP-Request nicht 16x ausführen um zu erfahren, ob die einzelnen Kanäle gesetzt sind sondern möchte einmal "blockweise" den Wert lesen und wenn der neue Wert da ist, die anderen Objekte über das Update in Kenntnis setzen und in einer Member-Funktion die Verundung durchführen.

    Welche anderen Objekte? Sind es z.B. 16 an der Zahl, jedes zuständig für ein Bit, und du wisst nur die betroffenen benachrichtigen oder alle? Und was für eine Member-Funktion bzw. Member wovon?

    D.h. ich möchte im Originalobjekt die Eingangsvariable von der Hardware setzen und in den anderen Objekten auf diese Variable referenzieren.

    Was für ein OriginalObjekt? Das XHR-Objekt?
    Zeig' doch mal etwas Code...

    Gruß, Don P

    1. Hallo,

      Ich vermute jedoch, die Antwort ist nein.

      Ich vermute dagegen, die Antwort ist ja. Nicht ganz trivial, aber das sollte gehen. Leider verstehe ich deine deine Beschreibung nur ganz grob:

      ich möchte aber den HTTP-Request nicht 16x ausführen um zu erfahren, ob die einzelnen Kanäle gesetzt sind sondern möchte einmal "blockweise" den Wert lesen und wenn der neue Wert da ist, die anderen Objekte über das Update in Kenntnis setzen und in einer Member-Funktion die Verundung durchführen.

      Welche anderen Objekte? Sind es z.B. 16 an der Zahl, jedes zuständig für ein Bit, und du wisst nur die betroffenen benachrichtigen oder alle? Und was für eine Member-Funktion bzw. Member wovon?

      var2 bis var16 sind die anderen Objekte. Es können 16 sein, können auch mehr sein, hängt dann von der Konfig ab. Rest siehe unten...

      D.h. ich möchte im Originalobjekt die Eingangsvariable von der Hardware setzen und in den anderen Objekten auf diese Variable referenzieren.

      Was für ein OriginalObjekt? Das XHR-Objekt?

      var1 ist mein Originalobjekt

      Zeig' doch mal etwas Code...

      Unnötiges Zeug (wonach die Variablen refreshed werden) habe ich rausgeschmissen...

        
      function oADSVar(_inChannel, _inCurrentValue)  
      {  
          // Kanalnummer, beginnend bei 1  
          this.inChannel       = _inChannel;  
          this.inCurrentValue  = _inCurrentValue;  
        
          this.setCurrVal = function(_inCurrVal)  
          {  
              if (this.inChannel != "")  
              {  
                  ( ( _inCurrVal & Math.pow(2, (this.inChannel)-1) ) > 0) ? this.inCurrentValue = 1 : this.inCurrentValue = 0;  
              }  
          }  
      }  
        
      function setCurrVal2()  
      {  
          alert("update!");  
      }  
      var var1 = new oADSVar("1" "");  
      var var2 = new oADSVar("2", var1.inCurrentValue);  
        
      //var2.inCurrentValue.addEventListener('change',setCurrVal2,false); -> ergibt Fehler  
      var2.inCurrentValue.onChange = setCurrVal2; // fehlerfrei, aber funtkioniert nicht  
        
      
      

      var2 bis var16 soll nur noch die Referenz auf var1.inCurrentValue erhalten und bei deren Änderung soll in zB var2 setCurrVal aufgerufen werden (oder wenn es nicht anders geht, dann eine externe Funtkion wie setCurrVal2)

      Hoffe, jetzt ist es verständlicher...?

      1. Hi,

        Ich vermute jedoch, die Antwort ist nein.

        Javascript ist nicht darauf ausgelegt, auf Bit-Ebene zu adressieren und zu operieren.

        ich möchte aber den HTTP-Request nicht 16x ausführen um zu erfahren, ob die einzelnen Kanäle gesetzt sind

        Das wäre ja auch Unfug - hole alle 16bit auf einmal und vergleiche sie mit dem vorherigen Stand.
        Ist das gesamte 16bit-Wort unverändert, ist zwangsläufig auch jedes Bit unverändert.
        Ist das gesamte Wort jedoch verändert, kannst du daraus alle 16bit neu extrahieren, ohne dafür noch einen HTTP-Request loszutreten.

        ( ( _inCurrVal & Math.pow(2, (this.inChannel)-1) ) > 0) ? this.inCurrentValue = 1 : this.inCurrentValue = 0;

        Schön, dass du den ternären Operator kennst - diese Anweisung ist dennoch maximal umständlich geschrieben. Wenn du schon den ternären Operator benutzt, ziehe die Teilausdrücke vor, die in beiden Fällen gleich sind; in deinem Fall ist das die linke Seite der Zuweisung. Außerdem ist es mit Elefanten auf Mücken geschossen, wenn du das Math-Objekt und die Potenzierung bemühst, nur um eine Bitmaske zu berechnen, die man ebensogut durch eine primitive Bitshift-Operation haben kann.
        Effizienter und übersichtlicher:

        this.inCurrentValue = ((_inCurrVal & (1<<this.inChannel))!=0);

        Gut, so hast du nicht 1 und 0, sondern true und false - aber das ist ja letztendlich dasselbe.

        Hoffe, jetzt ist es verständlicher...?

        Mir war schon vorher klar, was du willst - aber das ist so nicht vorgesehen.

        Ciao,
         Martin

        --
        Chef zum Bewerber: Es gibt zwei Dinge, auf die ich allergrößten Wert lege. Das eine ist Sauberkeit! Haben Sie übrigens die Schuhe auf der Matte abgetreten? - Ja, selbstverständlich. - Gut. Das andere ist uneingeschränkte Ehrlichkeit. Übrigens, draußen liegt gar keine Fußmatte.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Hi,

          Ich vermute jedoch, die Antwort ist nein.

          Javascript ist nicht darauf ausgelegt, auf Bit-Ebene zu adressieren und zu operieren.

          Nun, das macht sowieso meine PHP-Klasse und nicht JS, wenn Du den Zugriff auf die Hardware meinst.

          ich möchte aber den HTTP-Request nicht 16x ausführen um zu erfahren, ob die einzelnen Kanäle gesetzt sind

          Das wäre ja auch Unfug - hole alle 16bit auf einmal und vergleiche sie mit dem vorherigen Stand.

          Ist ja mein Plan, sonst hätte ich den Thread nicht gestartet. Allerdings möchte ich diesen Vorgang vor dem Anwender verstecken, das Projekt soll dann irgenwann auf SourceForge wandern und Leuten Freude bedeuten, die  nicht so tief in die Materie tauchen möchten.

          Ist das gesamte 16bit-Wort unverändert, ist zwangsläufig auch jedes Bit unverändert.
          Ist das gesamte Wort jedoch verändert, kannst du daraus alle 16bit neu extrahieren, ohne dafür noch einen HTTP-Request loszutreten.

          ( ( _inCurrVal & Math.pow(2, (this.inChannel)-1) ) > 0) ? this.inCurrentValue = 1 : this.inCurrentValue = 0;

          Schön, dass du den ternären Operator kennst - diese Anweisung ist dennoch maximal umständlich geschrieben. Wenn du schon den ternären Operator benutzt, ziehe die Teilausdrücke vor, die in beiden Fällen gleich sind; in deinem Fall ist das die linke Seite der Zuweisung. Außerdem ist es mit Elefanten auf Mücken geschossen, wenn du das Math-Objekt und die Potenzierung bemühst, nur um eine Bitmaske zu berechnen, die man ebensogut durch eine primitive Bitshift-Operation haben kann.

          this.inCurrentValue = ( ( _inCurrVal & Math.pow(2, (this.inChannel)-1) ) > 0)

          wollte er nicht haben und auf die bei uC's ständig verwendete Lösung habe ich nicht gedacht.

          Effizienter und übersichtlicher:

          this.inCurrentValue = ((_inCurrVal & (1<<this.inChannel))!=0);

          Gut, so hast du nicht 1 und 0, sondern true und false - aber das ist ja letztendlich dasselbe.

          Hoffe, jetzt ist es verständlicher...?

          Mir war schon vorher klar, was du willst - aber das ist so nicht vorgesehen.

          Jetzt bin ich nur gespannt, ob jemanden doch eine Lösung einfällt oder ob ich ein Workaround bauen muss...:)

          1. Moin!

            Javascript ist nicht darauf ausgelegt, auf Bit-Ebene zu adressieren und zu operieren.

            Nun, das macht sowieso meine PHP-Klasse und nicht JS, wenn Du den Zugriff auf die Hardware meinst.

            Dann mach dir das Leben doch bitte einfach und lass die Infos passgenau in PHP aufdröseln und als passend formatiertes JSON-Objekt für alle deine Kanäle zurückgeben.

            Beispielsweise direkt als Array:

            [0,1,1,0,0,1,0,0]

            Acht Kanäle, benutzungsfertig ausgepackt für Javascript. :)

            - Sven Rautenberg

          2. Hallo,

            Allerdings möchte ich diesen Vorgang vor dem Anwender verstecken, das Projekt soll dann irgenwann auf SourceForge wandern und Leuten Freude bedeuten, die  nicht so tief in die Materie tauchen möchten.

            Schlechten Code veröffentlichen und anderen damit imponieren?
            An welche Zielgruppe hast du dabei gedacht? *kopfschüttel*

            Gruß, Don P

            1. Hallo,

              Allerdings möchte ich diesen Vorgang vor dem Anwender verstecken, das Projekt soll dann irgenwann auf SourceForge wandern und Leuten Freude bedeuten, die  nicht so tief in die Materie tauchen möchten.

              Schlechten Code veröffentlichen und anderen damit imponieren?
              An welche Zielgruppe hast du dabei gedacht? *kopfschüttel*

              Oder jemanden eine Menge Zeit ersparen und eine funktionierende Lösung anbieten?

              "Send a patch", wenn Du so herablassend redest.

        2. @@Der Martin:

          nuqneH

          Ist das gesamte 16bit-Wort unverändert, ist zwangsläufig auch jedes Bit unverändert.
          Ist das gesamte Wort jedoch verändert, kannst du daraus alle 16bit neu extrahieren, ohne dafür noch einen HTTP-Request loszutreten.

          Welche Bits sich geändert haben, lässt sich durch XOR recht einfach feststellen: wenn oldValue ^ newValue bspw. 1000000000100101 (binär) ergibt, dann haben sich das 0. (LSB), 2., 5. und 15. (HSB) Bit geändert.

          Qapla'

          --
          Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
          (Mark Twain)
  2. Hallo,

    kann man an eine Member-Variable ein onchange Event hängen, sodass eine Funktion ausgeführt wird, wenn sich die Variable ändert. Ich vermute jedoch, die Antwort ist nein.

    ECMAScript 5 kennt Getter und Setter:
    http://www.peterkroener.de/ecmascript-5-die-nachste-version-von-javascript-teil-3-property-descriptors-getter-und-setter-funktionen/
    http://molily.de/weblog/ecmascript5#property-descriptors-2

    Ältere Browser unterstützen z.T. andere Syntaxen für Getter und Setter (defineSetter bzw. die mit ES5 ebenfalls standardisierte get/set in Object-Literalen). Dennoch lassen sich nicht alle Browser abdecken, der Internet Explorer < 9 kennt diese Schreibweisen nicht.

    Wie schon immer kannst du natürlich eigene Setter-Methoden anstatt von Eigenschaften verwenden, also eine Methode namens setFoo statt bloß eine Eigenschaft foo. Zudem kannst du dir ein Event-Listening bauen, sodass du Handler-Funktionen für das Ereignis der Änderung registrieren kannst. Beim Aufruf der Funktion kannst du die Handler dann auslösen. Mit ES5-Settern ist das natürlich noch einfacher.

    Mathias

    1. Hallo,

      kann man an eine Member-Variable ein onchange Event hängen, sodass eine Funktion ausgeführt wird, wenn sich die Variable ändert. Ich vermute jedoch, die Antwort ist nein.

      ECMAScript 5 kennt Getter und Setter:
      http://www.peterkroener.de/ecmascript-5-die-nachste-version-von-javascript-teil-3-property-descriptors-getter-und-setter-funktionen/
      http://molily.de/weblog/ecmascript5#property-descriptors-2

      Ältere Browser unterstützen z.T. andere Syntaxen für Getter und Setter (defineSetter bzw. die mit ES5 ebenfalls standardisierte get/set in Object-Literalen). Dennoch lassen sich nicht alle Browser abdecken, der Internet Explorer < 9 kennt diese Schreibweisen nicht.

      Wie schon immer kannst du natürlich eigene Setter-Methoden anstatt von Eigenschaften verwenden, also eine Methode namens setFoo statt bloß eine Eigenschaft foo. Zudem kannst du dir ein Event-Listening bauen, sodass du Handler-Funktionen für das Ereignis der Änderung registrieren kannst. Beim Aufruf der Funktion kannst du die Handler dann auslösen. Mit ES5-Settern ist das natürlich noch einfacher.

      Vielen Dank für die Links - muss mir ein wenig Zeit nehmen, um die (für mich) neuen Konzepte zu "verdauen".
      Demnach könnte ich eine Funktion statt der Eigenschaft inCurrentValue vorsehen, die dann inCurrentValue setzt und zusätzlich noch andere Aufgaben übernimmt.
      Wie weiss nur diese Funktion möglichst einfach, an welche Objekte die Werte zum Weitergeben sind? Abgesehen von der fehleranfälligen Möglichkeit, die Objektnamen als Parameter zu übergeben?
      Oder bin ich auf dem falschen Weg....?

      1. Demnach könnte ich eine Funktion statt der Eigenschaft inCurrentValue vorsehen, die dann inCurrentValue setzt und zusätzlich noch andere Aufgaben übernimmt.

        Richtig.

        Wie weiss nur diese Funktion möglichst einfach, an welche Objekte die Werte zum Weitergeben sind?

        Wie gesagt, am besten durch »Loose Coupling«: indem du dir ein Event-Modell baust und vorher für das Ereignis Handler registrierst. Die Setter-Funktion triggert dann einen Event, sodass die Liste der Handler durchlaufen und jeder aufgerufen wird.

        Siehe beispielsweise das Event-Modul in Backbone (Quellcode). Das kann man natürlich auch einfacher lösen: Einer Registrierfunktion, einer Handler-Liste und einer Trigger-Funktion, die die Handler aufruft.

        Mathias

        1. Demnach könnte ich eine Funktion statt der Eigenschaft inCurrentValue vorsehen, die dann inCurrentValue setzt und zusätzlich noch andere Aufgaben übernimmt.

          Richtig.

          Wie weiss nur diese Funktion möglichst einfach, an welche Objekte die Werte zum Weitergeben sind?

          Wie gesagt, am besten durch »Loose Coupling«: indem du dir ein Event-Modell baust und vorher für das Ereignis Handler registrierst. Die Setter-Funktion triggert dann einen Event, sodass die Liste der Handler durchlaufen und jeder aufgerufen wird.

          Siehe beispielsweise das Event-Modul in Backbone (Quellcode). Das kann man natürlich auch einfacher lösen: Einer Registrierfunktion, einer Handler-Liste und einer Trigger-Funktion, die die Handler aufruft.

          Falls das jemand noch liest:
          Danke für die Links, habe ich mir ein wenig angeschaut. Anhand dessen dann überlegt, dass ich kein weiteres Framework einbauen möchte, damit ja alles mit allem kompatibel bleibt (tut's eh nicht...*gg*)

          auf jeden Fall habe ich es so gelöst:

            
          function oADSVar(_inChannel, _inCurrentValue)  
          {  
              // Kanalnummer, beginnend bei 1  
              this.inChannel       = _inChannel;  
              this.inCurrentValue  = _inCurrentValue;  
              this.aObservers      = new Array();  
            
              this.setCurrVal = function(_inCurrVal)  
              {  
                  var j = 0;  
                  if (this.inChannel != "")  
                  {  
                      ( ( _inCurrVal & Math.pow(2, (this.inChannel)-1) ) > 0) ? this.inCurrentValue = 1 : this.inCurrentValue = 0;  
                  }  
            
                  for ( this.j = 0; this.j < this.aObservers.length; this.j++)  
                  {  
                      var oObj = eval(this.aObservers[this.j]);  
                      oObj.setCurrVal(_inCurrVal);  
                  }  
            
              }  
              this.attach = function (_sName)  
              {  
                  this.aObservers.push(_sName);  
                  this.bObserved = true;  
                  return this.inCurrentValue;  
              }  
          }  
            
          var var1 = new oADSVar("1" "");  
          var var2 = new oADSVar("2", var1.attach("var2"));  
          
          

          var2 registriert sich also bei var1 und var1 sorgt beim Update der eigenen Werte wiederum um die Verteilung. Vielleicht nicht die schönste Lösung, aber definitiv einfach.

          Der Aufruf var1.attach("var2") gefällt mir noch nicht ganz, wäre cool, wenn man den Namen des Observer-Objekts automatisch übergeben könnte. Werde dazu noch etwas überlegen.

          1. Hallo,

            auf jeden Fall habe ich es so gelöst:

            ( ( _inCurrVal & Math.pow(2, (this.inChannel)-1) ) > 0) ? this.inCurrentValue = 1 : this.inCurrentValue = 0;

              
            [Unbelehrbar](https://forum.selfhtml.org/?t=205648&m=1394530)? Folgendes  
            ~~~javascript
              
            this.inCurrentValue = +(_inCurrVal >= 1<<this.inChannel);  
            
            

            liefert die gleichen Ergebnisse, nur weniger umständlich.

            Auch der Rest erscheint mir umständlich. Eval sollte man immer vermeiden.
            Und Musst du unbedingt einzelne Variablen var1, var2 etc. haben? Warum nicht einfach ein Array mit den Objekten drin? Du hast ja schon eins, aber am falschen Ort.
            So bekommst du x Objekte, alle mit einem aObservers-Array, einer attach-Methode usw., die du aber scheint's gar nicht verwenden willst.

            Sorry, aber das ist nicht wirklich durchdacht => für die Tonne ;)

            Gruß, Don P

            1. Hallo,

              auf jeden Fall habe ich es so gelöst:

              ( ( _inCurrVal & Math.pow(2, (this.inChannel)-1) ) > 0) ? this.inCurrentValue = 1 : this.inCurrentValue = 0;

              
              >   
              > [Unbelehrbar](https://forum.selfhtml.org/?t=205648&m=1394530)? Folgendes  
              > ~~~javascript
                
              
              > this.inCurrentValue = +(_inCurrVal >= 1<<this.inChannel);  
              > 
              
              

              liefert die gleichen Ergebnisse, nur weniger umständlich.

              Nein, das habe ich nur aus dem original Post genommen und zu spät bemerkt. AFAIK kann man keine Beiträge hier editieren?

              Auch der Rest erscheint mir umständlich. Eval sollte man immer vermeiden.

              Bitte um Info, warum eval böse ist...?

              Und Musst du unbedingt einzelne Variablen var1, var2 etc. haben? Warum nicht einfach ein Array mit den Objekten drin? Du hast ja schon eins, aber am falschen Ort.

              Muss sein. Die einzelnen Bits können dann später total unterschiedliche Darstellungen haben und ich erachte es derzeit für viel einfacher, die Sache so handzuhaben.
              Ein weiteres Argument ist: ich brauche nicht immer alle 16 Bits, es könnte sein, dass manchmal nur ein einziges Bit benötigt wird (Hintergrund: ich bau gerade ein kleines SCADA oder kleine Visualisierung für SPSn so zum Spass)

              So bekommst du x Objekte, alle mit einem aObservers-Array, einer attach-Methode usw., die du aber scheint's gar nicht verwenden willst.

              Ich habe auch überlegt, zwei verschiedene Objekte (Observer und Subjekt) zu erstellen, die von einem gemeinsamen Objekt die Gemeinsamkeiten erben könnten -> kann derzeit noch die Nachteile gegenüber den Vorteilen nicht abschätzen (bez. Codegröße, Geschwindigkeit, Speicherverbrauch, etc., etc.)

              1. Hallo,

                Auch der Rest erscheint mir umständlich. Eval sollte man immer vermeiden.

                Bitte um Info, warum eval böse ist...?

                Den Spruch scheinst du ja zu kennen. Dazu gibt's auch massenhaft Info.

                Und Musst du unbedingt einzelne Variablen var1, var2 etc. haben? Warum nicht einfach ein Array mit den Objekten drin? Du hast ja schon eins, aber am falschen Ort.
                Muss sein. Die einzelnen Bits können dann später total unterschiedliche Darstellungen haben und ich erachte es derzeit für viel einfacher, die Sache so handzuhaben.

                Was ist daran einfach? Nichtssagende Variablennamen erfinden und als Strings an Eval übergeben, nur um wieder an den Inhalt der Variablen zu kommen ist alles andere als einfach.

                Ein weiteres Argument ist: ich brauche nicht immer alle 16 Bits, es könnte sein, dass manchmal nur ein einziges Bit benötigt wird (Hintergrund: ich bau gerade ein kleines SCADA oder kleine Visualisierung für SPSn so zum Spass)

                Das ist doch kein Argument für einzelne benannte Variablen statt eines Arrays. Mit z.B. der Zuweisung
                bitObjects[bitNr] = new bitObject(parameter);
                Hast du dein passendes Bit-Objekt erzeugt und kannst jederzeit mit bitObjects[bitNr] darauf zugreifen, statt über etwas wie Eval("varX");.

                So bekommst du x Objekte, alle mit einem aObservers-Array, einer attach-Methode usw., die du aber scheint's gar nicht verwenden willst.

                Ich habe auch überlegt, zwei verschiedene Objekte (Observer und Subjekt) zu erstellen, die von einem gemeinsamen Objekt die Gemeinsamkeiten erben könnten -> kann derzeit noch die Nachteile gegenüber den Vorteilen nicht abschätzen (bez. Codegröße, Geschwindigkeit, Speicherverbrauch, etc., etc.)

                Vererbung hat in JavaScript keine Nachteile bezgl. Codegröße, Geschwindigkeit, Speicherverbrauch, etc., ganz im Gegenteil.
                Überlege dir, was die einzelnen Bit-Objekte wirklich enthalten bzw. tun sollen und erzeuge genau solche Objekte dann.
                Diese Bit-Objekte speicherst du wie gesagt in einem Array (einfach über den Index zuzugreifen statt über einen Evaluierten Namen) und deklarierst noch eine Funktion, die das Array durchläuft und alles Notwendige mit ihnen anstellt.

                Gruß, Don P

                1. Hallo,

                  Hier mal ein Beispiel, wie das etwa aussehen könnte, ganz ohne Vererbung:

                  var bitController = {  
                    
                    bitObjects: [],  
                    
                    bit: function(channel) {return bitObjects[channel]; },  
                    
                    newBit: function(inChannel) {  
                    
                      !bitObjects[inChannel] && bitObjects.push(  
                         {  
                           channel: inChannel,  
                           value: undefined,  
                           setValue: function(inCurrVal) {  
                               this.value = +(inCurrVal >= 1<<this.channel);  
                           }  
                    
                           /* hier evtl. weitere Eigenschaften und Methoden */  
                         }  
                      );  
                      return bitController;  
                    },  
                    
                    updateBits: function(inCurrVal) {  
                    
                      var i, oo = this.bitObjects, len = oo.length ;  
                      for(i=0; i<len; i++) {oo.setValue(inCurrVal);}  
                    }  
                    
                  };
                  

                  bitController.newBit(1); // Objekt für Bit 1 anlegen
                  bitController.newBit(5); // Objekt für Bit 5 anlegen
                  bitController.updateBits(bitsVonHardware); // Alle aktualisieren
                  bitController.newBit(6).updateBits(bitsVonHardware); // Obj. f. Bit 6 anlegen & alle aktualisieren

                  var ch5_Value = bitController.bit(5).value; // Bit 5 auslesen

                  Alles ungetestet, nur mal so als Denkanstoß.

                  updateBits() könnte man problemlos so gestalten, dass für jedes existierende Hardware-Bit ggf. erst ein neues BitObjekt angelegt wird, falls es noch nicht existiert.

                  Gruß, Don P

                2. Und das funktioniert sogar:

                    
                  /************************************************************************/  
                  var bitMaster = {  
                    
                    bitObjects: [],  
                    
                    bit: function(channel) { return this.bitObjects[channel]; },  
                    
                    newBit: function(inChannel) {  
                    
                      this.bitObjects[inChannel] = {  
                    
                        value: undefined,  
                        channel: inChannel,  
                        setValue: function(fromAJAX) { return this.value = +((fromAJAX & 1<<this.channel) > 0); }  
                    
                        /* hier evtl. weitere Eigenschaften und Methoden eines Bit-Objekts */  
                      };  
                    
                      return bitMaster;  
                    },  
                    
                    updateBits: function(fromAJAX) {  
                    
                      var i, bit, a = this.bitObjects, len = a.length;  
                      for(i=0; i<len; i++) { (bit = a[i]) && bit.setValue(fromAJAX); }  
                      return a;  
                    }  
                    
                  };  
                    
                  /******************** Testlauf: *****************************/  
                    
                  // Channel 0 anlegen:  
                  bitMaster.newBit(0);  
                  // Channel 2 anlegen:  
                  bitMaster.newBit(2);  
                  // Channel 4 anlegen und alle aktualisieren mit 21 (10101):  
                  bitMaster.newBit(4).updateBits(21);  
                    
                  alert(bitMaster.bit(0).value); // 1 ( Wert in Channel 0)  
                  alert(bitMaster.bit(2).value); // 1 ( Wert in Channel 2)  
                  alert(bitMaster.bit(4).value); // 1 ( Wert in Channel 4)  
                    
                  // Mit 11 (01011) aktualisieren und den Wert von Channel 4 speichern:  
                  var val4 = bitMaster.updateBits(11)[4].value;  
                    
                  alert(bitMaster.bit(0).value); // 1 ( Wert in Channel 0)  
                  alert(bitMaster.bit(2).value); // 0 ( Wert in Channel 2)  
                  alert(val4);                   // 0 ( Wert in Channel 4)  
                  
                  

                  Gruß, Don P

                3. Überlege dir, was die einzelnen Bit-Objekte wirklich enthalten bzw. tun sollen und erzeuge genau solche Objekte dann.
                  Diese Bit-Objekte speicherst du wie gesagt in einem Array [...] und deklarierst noch eine Funktion, die das Array durchläuft und alles Notwendige mit ihnen anstellt.

                  Das geht auch mit den Methoden direkt im bitObjects-Array:

                    
                  /************************************************************************/  
                  var bitObjects = [];  
                    
                  bitObjects.newBit = function(inChannel) {  
                    
                      this[inChannel] = {  
                    
                        value: undefined,  
                        channel: inChannel,  
                        setValue: function(fromAJAX) { return this.value = +((fromAJAX & 1<<this.channel) > 0); }  
                    
                        /* hier weitere Eigenschaften und Methoden eines Bit-Objekts */  
                      };  
                    
                      return this;  
                  };  
                    
                  bitObjects.updateBits = function(fromAJAX) {  
                    
                      var i, bit, len = this.length;  
                      for(i=0; i<len; i++) { (bit = this[i]) && bit.setValue(fromAJAX); }  
                      return this;  
                  };  
                    
                  /******************** Testlauf: *****************************/  
                    
                  // Channel 0 anlegen:  
                  bitObjects.newBit(0);  
                  // Channel 2 anlegen:  
                  bitObjects.newBit(2);  
                  // Channel 4 anlegen und alle aktualisieren mit 21 (10101):  
                  bitObjects.newBit(4).updateBits(21);  
                    
                  alert(bitObjects[0].value); // 1 ( Wert in Channel 0)  
                  alert(bitObjects[2].value); // 1 ( Wert in Channel 2)  
                  alert(bitObjects[4].value); // 1 ( Wert in Channel 4)  
                    
                  // Mit 11 (01011) aktualisieren und den Wert von Channel 4 speichern:  
                  var val4 = bitObjects.updateBits(11)[4].value;  
                    
                  alert(bitObjects[0].value); // 1 ( Wert in Channel 0)  
                  alert(bitObjects[2].value); // 0 ( Wert in Channel 2)  
                  alert(val4);                   // 0 ( Wert in Channel 4)  
                  
                  

                  Gruß, Don P

              2. Auch der Rest erscheint mir umständlich. Eval sollte man immer vermeiden.

                Bitte um Info, warum eval böse ist...?

                eval() ist böse, weil es viele Leute für Zwecke verwenden, für die es nicht gedacht und nicht geeignet ist. In der Regel wird es verwendet, weil das Wissen um bessere Lösungen, also Wissen über JavaScript fehlt (bitte nicht persönlich nehmen). Fast alle eval-Anwendungen lassen sich sauberer, schneller, robuster, JavaScript-typischer lösen. Die verbleibenden sind die, bei denen man wirklich große Mengen JavaScript-Code aus einem String ausführen will. Aber auch dafür gibt es Alternativen wie new Function().

                Mathias

          2. Der Aufruf var1.attach("var2") gefällt mir noch nicht ganz, wäre cool, wenn man den Namen des Observer-Objekts automatisch übergeben könnte.

            Der Name ist irrelevant. Du kannst das Objekt übergeben. Du solltest nicht mit Variablennamen und eval() arbeiten, wenn du auch Objekte oder Funktionen übergeben kannst.

            Das Interface sollte so funktionieren:

            var1.addObserver(var2)

            Oder attach, wie es bei dir heißt.
            Das ist auch unproblematisch zu implementieren.

            this.aObservers      = new Array();

            Der Array-Literal [] schreibt sich kürzer und ist etwas schneller als new Array.

            this.setCurrVal = function(_inCurrVal)
                {
                    var j = 0;

            Hier deklarierst du eine Variable, die du nicht nutzt, aber nutzen solltest.

            for ( this.j = 0; this.j < this.aObservers.length; this.j++)
                    {
                        var oObj = eval(this.aObservers[this.j]);
                        oObj.setCurrVal(_inCurrVal);
                    }

            Wenn du das Objekt anstatt des Namens übergibst, so kannst du dir das eval() sparen und bekommst mit this.aObservers[j] direkt das gewünschte oADSVar-Instanzobjekt.

            this.attach = function (_sName)
                {
                    this.aObservers.push(_sName);

            Benenne die Variable um, speichere einfach das Objekt im Array.

            Mathias

          3. Siehe beispielsweise das Event-Modul in Backbone (Quellcode). …
            … Anhand dessen dann überlegt, dass ich kein weiteres Framework einbauen möchte, damit ja alles mit allem kompatibel bleibt (tut's eh nicht...*gg*)

            Zur Ergänzung: Backbone ist ein Framework, ja. Ich wollte dir nicht raten, es einzubauen, denn es hat mit deinem Ziel offenbar wenig zu tun. Es enthält jedoch eine einfache Implementierung für einen Event-Dispatcher (der Link geht auf direkt auf die Codezeile). Dieser Code ist 58 Zeilen lang und soweit ich sehe eigenständig und herauslösbar. Du musst den nicht übernehmen, er war nur ein Beispiel für eine kompakte allgemeine Umsetzung. peterS hat eine weitere verlinkt.

            Mathias

      2. gruss BBKing,

        ich poste mal einen link mit erlaueterungen zum wahrscheinlich
        gesuchten eventgetriebenen loesungsansatz mit dem sperrigen
        titel [EventDispatcher] - eine Implementierung von »Signals and Slots«.

        aktuelle implementierungen des inzwischen zu [EventTargetProvider]
        umgetauften ansatzes finden sich auf github z.b. unter
        https://github.com/petsel/javascript-api-extensions/blob/master/core/SignalsAndSlots/EventTargetProvider.js.

        auf dieser grundlage entwickle ich seit jahren komplexe javascripte,
        deren komponenten untereinander loser koppelung beduerfen.

        so long - peterS. - pseliger@gmx.net

        --
        »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
        Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
        ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:]
        1. Hallo peterS,

          auf dieser grundlage entwickle ich seit jahren komplexe javascripte,
          deren komponenten untereinander loser koppelung beduerfen.

          Ich auch, dank deinem genialenn Eventdispatcher :). Wusste gar nicht, dass er inzwischen weiterentwickelt wurde.

          Gruß, Don P

      3. Hallo,

        Vielen Dank für die Links - muss mir ein wenig Zeit nehmen, um die (für mich) neuen Konzepte zu "verdauen".

        Es gibt noch ein anderes Konzept (um die Verwirrung komplett zu machen), das vielleicht interessant sein könnte. Du schreibst ja:

        Objekt liest über AJAX Werte von einer Hardware.

        Wenn die Änderungen von der Harware ausgehen, ist es vielleicht besser, nicht die Clients periodisch per AJAX beim Server anfragen zu lassen, sondern sie vom Server aus bei Änderung zu benachrichtigen. APE kann das angeblich leisten.

        Demnach könnte ich eine Funktion statt der Eigenschaft inCurrentValue vorsehen, die dann inCurrentValue setzt und zusätzlich noch andere Aufgaben übernimmt.

        Da wohl alle Objekte mit demselben inCurrentValue arbeiten sollen, wäre es wohl angebracht, inCurrentValue als mehr oder weniger globale Variable zu deklarieren, statt als Eigenschaft im Konstruktor deines Hauptobjekts. Das würde Getter/Setter für inCurrentValue überflüssig machen.

        Gruß, Don P