Karl: Objektname eines Objekts?

Hallo,

kennt Jemand eine Möglichkeit, den JavaScript-Namen eines Objekts herauszukriegen?

Beispiel:

objekt1 = new obj();
alert(objekt1.name);

Mich würde folgende Ausgabe erfreuen: "objekt1"

Hintergrund ist ein Framework, das HTML-Tags erzeugt, deren ID idealerweise dem Namen des Objekts entspricht.

Mir ist schon klar, dass man sich einfach selbst ein Feld erzeugen kann, welches den Namen des Objekts als String enthält. Aber vielleicht geht das ja auch einfacher?

Vielen Dank im Voraus!

lg
Karl

  1. Hallo,

    Mir ist schon klar, dass man sich einfach selbst ein Feld erzeugen kann, welches den Namen des Objekts als String enthält. Aber vielleicht geht das ja auch einfacher?

    Nein.

    Hintergrund ist ein Framework, das HTML-Tags erzeugt, deren ID idealerweise dem Namen des Objekts entspricht.

    Es scheint mir immer unverständlich, wenn jemand Code-interne Organisation und Benennung mit einer bestimmten »Ausgabe« koppeln will. Variablennamen müssen verständlich sein, sind darüber hinaus aber Schall und Rauch. Wenn man eine ID z.B. zur Adressierung außerhalb des JavaScript-Codes via CSS braucht (wozu brauchst du sie?), sollte man eine wählen, die vornehmlich diesem Zweck angemessen ist. Ich persönlich fand es bisher nicht erstrebenswert, ein bestimmtes Ergebnis fest an einen bestimmten Variablennamen zu koppeln.

    Mathias

    1. Hallo Mathias,

      Hintergrund ist folgender: ich schreibe eine Art GUI-Framework. Es soll Elemente wie Forms, Edits, Labels, Scrollbars etc. enthalten.

      Beispiel in JavaScript:

      form1 = new TForm();
      form1.setBounds(30,30,300,200);
      button1 = new TButton(form1);
      button1.setBounds(50,50,70,20);
      button1.setCaption("Hallo Welt");
      form1.show();

      Dieser Code soll ein (mit der Maus verschiebbares) Dialogfeld mit einem Button erzeugen. Das ist natürlich nur ein sehr einfaches Beispiel.

      Nehmen wir zum Beispiel die Methode "setCaption" eines GUI-Objekts, in diesem Falle eines TButton. Die Implementierung der Methode könnte so einfach sein:

      function setCaption(fText)
      {
          el = document.getElementById(this.OBJEKTNAME);
          el.style.value = fText;
      }

      Doch genau da liegt das Problem: OBJEKTNAME steht stellvertretend für ein Feld des Objekts - was es aber scheinbar nicht gibt.

      Ich habe es jetzt anders gelöst. Aber es ist natürlich nicht so elegant.

      In diesem Fall wäre es eben sehr praktisch, wenn die IDs von INPUT-Elementen oder DIVs die Namen der JavaScript-Objekte, die sie repräsentieren, tragen würden.

      lg
      Kalle

      1. Nehmen wir zum Beispiel die Methode "setCaption" eines GUI-Objekts, in diesem Falle eines TButton. Die Implementierung der Methode könnte so einfach sein:

        function setCaption(fText)
        {
            el = document.getElementById(this.OBJEKTNAME);
            el.style.value = fText;
        }

        wozu brauchst du getElement?
        Wenn du das Element mit createElement() erzeugst ist der rückgabewert doch bereits die Referenz.

        Ich habe es jetzt anders gelöst. Aber es ist natürlich nicht so elegant.

        Wenn du es mit dem Rückgabewert von createElement gelöst hast, ist es eleganter.

        Struppi.

        --
        Javascript ist toll (Perl auch!)
        1. wozu brauchst du getElement?
          Wenn du das Element mit createElement() erzeugst ist der rückgabewert doch bereits die Referenz.

          Oops, sowas gibt es? *schäm*
          Gut zu wissen, das könnte die Lösung sein.
          Vielen Dank!

      2. gruss Karl,

        ...  ich schreibe eine Art GUI-Framework. Es soll Elemente wie
        Forms, Edits, Labels, Scrollbars etc. enthalten.

        Beispiel in JavaScript:

        form1 = new TForm();
        ...

        Dieser Code soll ein (mit der Maus verschiebbares) Dialogfeld
        mit einem Button erzeugen. Das ist natürlich nur ein sehr
        einfaches Beispiel. ... Die Implementierung der Methode könnte
        so einfach sein:

        function setCaption(fText)
        {
            el = document.getElementById(this.OBJEKTNAME);
            el.style.value = fText;
        }

        ... OBJEKTNAME steht stellvertretend für ein Feld des Objekts -
        was es aber scheinbar nicht gibt.

        so wie es aussieht, kapselst Du die Logik eines oder einer gruppe
           von DOM-knoten in einem JavaScript-objekt. die initialisierung des
           von Dir beispielhaft angegebenen objekts vom typ "tform" erledigt
           Deine konstruktorfunktion "TForm". Du musst nur sicherstellen, dass
           genau dort, oder meinetwegen auch in einer initialisierungsmethode
           das "tform"-objekt mindestens einen der betroffenen DOM-knoten
           als referenz an sich binden kann - z.b.:

        ~~~javascript var TForm = function (nodeObj) {

        this.domNode = nodeObj;
           //your code;
           };

          
           die beispielhafte methode "setCaption" liesse sich dann  
           so umsetzen:  
          
           ~~~javascript
        TForm.prototype.setCaption = function (fText) {  
          
             this.nodeObj.style.value = fText;  
           };
        

        Ich habe es jetzt anders gelöst.

        und wie?

        In diesem Fall wäre es eben sehr praktisch, wenn die IDs von
        INPUT-Elementen oder DIVs die Namen der JavaScript-Objekte,
        die sie repräsentieren, tragen würden.

        referenzen auf die von meinem JavaScript-objekt zu beeinflussenden
           dom-knoten sind in meinen augen naheliegender, da ich diese bei der
           objektinitialisierung sowiso "kennen" muss.

        by(t)e by(t)e - 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. Ich habe es jetzt anders gelöst.

          und wie?

          An DOM-Knoten habe ich noch gar nicht gedacht. Stattdessen übergebe ich im Konstruktor den Namen des Objekts als String.

          button1 = new TButton("button1");

          function TButton(fName)
          {
             this.name = fName;
          }

          ...und verwende diesen später bei der Erzeugung
          s = '<input id='+this.name+'>';

          ...und suche in der Methode setCaption das entsprechende Element
          element = document.getElementByID(this.name);

          Ist wie gesagt ziemlich uncool, aber eine bessere Lösung habe ich noch nicht gefunden. Das mit den DOM-Knoten muss ich mir mal ansehen :-)

          Danke auf jeden Fall schonmal.

          lg
          Karl

          1. An DOM-Knoten habe ich noch gar nicht gedacht. Stattdessen übergebe ich im Konstruktor den Namen des Objekts als String.

            button1 = new TButton("button1");

            function TButton(fName)
            {
               this.name = fName;
            }

            ...und verwende diesen später bei der Erzeugung
            s = '<input id='+this.name+'>';

            Du arbeitest anscheinend mit innerHTML. Besser wäre createElement() zu nutzen, aber auch so kannst du dir den Namen sparen, bzw. den Parameter.

            Wie Mathias schon andeutet:

            function TButton()
            {
                this.name = 'TButton' + TButton.index++;
            }
            TButton.index = 0;

            Ist wie gesagt ziemlich uncool, aber eine bessere Lösung habe ich noch nicht gefunden. Das mit den DOM-Knoten muss ich mir mal ansehen :-)

            Wäre cooler ;-)

            Struppi.

            --
            Javascript ist toll (Perl auch!)
          2. hallo again Karl,

            ... Das mit den DOM-Knoten muss ich mir mal ansehen :-)

            unbedingt.

            fuer faelle, wie in dem von Dir beschriebenen, recycle
               ich immer noch folgendes grob skizzierte schema:

            var DHTMLObject = function () {  
              
              this.constructor = arguments.callee;  
            /*  
              minimal initial code if necessary like:  
              - private properties,  
              - privileged public methods.  
            */  
              this.compile.apply(this, arguments);  
            };  
            DHTMLObject.prototype.compile = function (obj) { // for reinitialization.  
              
              var regXClassName = (/\bdhtmlObject\b/);  
              if (obj && obj.nodeType && obj.nodeName && obj.className && (obj.nodeType == 1) && (regXClassName.test(obj.className))) {  
              
                this.node = obj;  
              /*  
                major part of constructor code that not necessarily  
                needs to be run by the constructor function itself.  
              */  
                var self = this;  
                this.node.onmousedown = function (evt) {  
                  DHTMLObject.onMouseDown(evt, self);  
                };  
              }  
            };  
              
              
            DHTMLObject.onMouseDown = function (evtObj, dhtmlObj) {  
              
              evtObj = (window.event || evtObj);  
            //some more code;  
            };  
              
              
            DHTMLObject.elements = [];  
              
              
            DHTMLObject.initialize = function () {  
              
              if (window.opera && (DHTMLObject.elements.length >= 1)) {return;} // in order to fix the beneath mentioned opera 9 "onload" bug.  
              
              if (typeof document.getElementsByClassNames == "function") {  
              
                var i, obj, arr = document.getElementsByClassNames("dhtmlObject");  
                for (i=0; i<arr.length; ++i) {  
              
                  obj = arr[i];  
                  if (obj && (obj.nodeType == 1)) {  
              
                    DHTMLObject.elements[DHTMLObject.elements.length] = new DHTMLObject(obj);  
                  }  
                }  
              }  
            //alert("DHTMLObject.elements[" + (DHTMLObject.elements.length - 1) + "] : " + DHTMLObject.elements[DHTMLObject.elements.length - 1]);  
            };  
              
              
            if (window.addEventListener) {  
              window.addEventListener("load", DHTMLObject.initialize, true); // opera 9 behaves buggy on this - workaround got implied.  
            } else if (window.attachEvent) {  
              window.attachEvent("onload", DHTMLObject.initialize);  
            }
            

            dabei geht mein Dank wie immer an Dr. Thomas Meinike fuer seine
               pioniertat zu einem "getElementsByClassName", das mir seit dieser
               zeit als angepasstes "document.getElementsByClassNames" stets
               treue dienste leistet.

            letztgenanntes modul benoetigt wiederum die unterstuetzung der
               Array-methode "contains", die fuer nicht-gecko-getriebene browser
               immer noch nachgeruestet werden muss:
               schon ziemlich alt - http://www.pseliger.de/jsExtendedApi/jsApi.Array.contains.dev.js,
               nicht mehr so neu - http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozExtensions.js.

            eine entwicklungsseite verlinkt dann nur noch diese javascript-dateien zusammen mit
               ein paar stylesheet-angaben. im html-quelltext selber werden die zu initialisierenden
               [DHTMLObject]-objekte ueber den klassennamen des entsprechenden DOM-Knotens aufgespuert.
               in diesem fall muesste man einfach <[nodename] class="... dhtmlObject ..." /> schreiben.

            dieses grundpaket versetzt zumindest mich in die lage, innerhalb von wenigen minuten
               eine vernuenftige arbeitsgrundlage fuer selbstzustrickende GUI-elemente zu schaffen.

            by(t)e by(t)e - 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:]
      3. Hallo,

        Wie ich vermutet hatte, spielt der Variablenname keine besondere Rolle. Für deine Zwecke könnte sich das Objekt auch automatisch selbst eine ID geben (z.B. TForm plus eine fortlaufende Nummer). Muss es aber gar nicht. Du willst anscheinend in den Methoden einfach auf den im Konstruktor erzeugten Elementknoten zugreifen. Also speicherst du (siehe Peter) eine Referenz auf den Elementknoten am Objekt. Was auch oft nützlich ist: Eine Referenz auf die jeweilige Instanz am Elementobjekt speichern, sodass sie sich gegenseitig verlinken. (Was allerdings garantiert zu Speicherlecks im MSIE 6 führt.)

        Mathias