ichbinich: anonyme Funktion - öffentliche Methode aufrufen

Hallo,

var myfunc = (function() {  
  [...]  
  
  return {  
    publicMethod: function() {  
    }  
  };  
  
}());

Mit myfunc.publicMethod() kann ich nun die öffentliche Methode aufrufen.

Wie kann ich die Methode direkt aufrufen, also ohne die anonyme Funktion in einer Variable zu speichern? (Ich erhalte dabei immer die Meldung publicMethod is not defined)

Ich weiß, das man das mit require.js machen kann, kann(darf) ich hier aber nicht verwenden.

VG ichbinich

--
Kleiner Tipp:
Tofu schmeckt am besten, wenn man es kurz vor dem Servieren durch ein saftiges Steak ersetzt...
  1. hi ichbinich,

    Hallo,

    var myfunc = (function() {

    [...]

    return {
        publicMethod: function() {
        }
      };

    }());

    
    >   
    >   
    > Mit `myfunc.publicMethod()`{:.language-javascript} kann ich nun die öffentliche Methode aufrufen.  
    >   
      
    
    > Wie kann ich die Methode direkt aufrufen, also ohne die anonyme Funktion in einer Variable zu speichern?  
      
    Du speicherst nicht die Funktion in einer Variable. Du erhälst ein Objekt {} mit dieser Methode von der Funktion.  
      
    mfg  
      
    tami
    
    1. hi tami,

      hi ichbinich,

      Hallo,

      var myfunc = (function() {

      [...]

      return {
          publicMethod: function() {
          }
        };

      }());

      
      > >   
      > >   
      > > Mit `myfunc.publicMethod()`{:.language-javascript} kann ich nun die öffentliche Methode aufrufen.  
      > >   
      >   
      > > Wie kann ich die Methode direkt aufrufen, also ohne die anonyme Funktion in einer Variable zu speichern?  
      >   
      > Du speicherst nicht die Funktion in einer Variable. Du erhälst ein Objekt {} mit dieser Methode von der Funktion.  
      
      s.a.  
        
      ~~~javascript
        
      /*jslint browser: false, devel: true */  
      (function () {  
          "use strict";  
          return {  
              myMethod: function () {  
                  alert("hallo");  
              }  
          };  
      }()).myMethod();  
      
      

      mfg

      tami

      1. Hallo,

        Du speicherst nicht die Funktion in einer Variable. Du erhälst ein Objekt {} mit dieser Methode von der Funktion.

        ja, schon klar, falsch ausgedrückt.

        /*jslint browser: false, devel: true */
        (function () {
            "use strict";
            return {
                myMethod: function () {
                    alert("hallo");
                }
            };
        }()).myMethod();

          
        Damit wird die Methode sofort ausgeführt, ich muss sie aber bei bestimmter User-Aktion ausführen...  
          
        vg ichbinich  
        
        -- 
        Kleiner Tipp:  
        Tofu schmeckt am besten, wenn man es kurz vor dem Servieren durch ein saftiges Steak ersetzt...
        
        1. Hallo,

          ich muss sie aber bei bestimmter User-Aktion ausführen...

          Ich weiß nicht genau, was du vorhast. Auf das Funktionsobjekt kannst du zugreifen, indem du die Klammern weglässt (den Aufruf-Operator):

          myfunc.publicMethod

          Dieses Funktionsobjekt kannst du als Event-Handler registrieren:

          document.getElementById('someButton').addEventListener('click', myfunc.publicMethod);

          »myfunc« solltest du, wie tami vorschlägt, umbenennen, da es sich nicht um eine Funktion handelt.

          Hintergrund:
          http://molily.de/js/organisation-module.html
          http://molily.de/js/organisation-verfuegbarkeit.html

          Mathias

          1. Hallo,

            Ich weiß nicht genau, was du vorhast. Auf das Funktionsobjekt kannst du zugreifen, indem du die Klammern weglässt (den Aufruf-Operator):

            Ich möchte(muss) direkt publicMethod() aufrufen, das ist eine Vorgabe die ich habe, mein Javascriptcode muss gekapselt sein, und mittels publicMethod() (Name ist hier beispielhaft, ist aber fest vorgegeben).

            »myfunc« solltest du, wie tami vorschlägt, umbenennen, da es sich nicht um eine Funktion handelt.

            War nur hier fürs Posting schnell hingeschrieben, soll(muss) ja sowieso weg.

            http://molily.de/js/organisation-module.html
            http://molily.de/js/organisation-verfuegbarkeit.html

            Genau da findet sich aber nur ein Aufruf a la myObj.publicMethod().

            Was ich brauche ist:

            (function() {  
              [...]  
              
              return {  
                publicMethod: function() {  
                }  
              };  
              
            }());  
              
            publicMethod();
            

            vg ichbinich

            --
            Kleiner Tipp:
            Tofu schmeckt am besten, wenn man es kurz vor dem Servieren durch ein saftiges Steak ersetzt...
            1. Hallo,

              Ich möchte(muss) direkt publicMethod() aufrufen, das ist eine Vorgabe die ich habe, mein Javascriptcode muss gekapselt sein, und mittels publicMethod() (Name ist hier beispielhaft, ist aber fest vorgegeben).

              Jetzt kommen wir der Sache näher! Du willst also gar kein Objekt zurückgeben, sondern bloß die Funktion, richtig?

              Was ich brauche ist:

              (function() {

              [...]

              return {
                  publicMethod: function() {
                  }
                };

              }());

              publicMethod();

                
              Dann gib kein Objekt {…} zurück, sondern direkt das Funktionsobjekt:  
                
              ~~~javascript
              var generateID = (function() {  
                var counter = 0;  
                return function() {  
                  return ++counter;  
                };  
              })();  
                
              alert(generateID());  
              alert(generateID());  
              alert(generateID());  
              alert(typeof counter); // undefined
              

              Mathias

              1. Hallo,

                Jetzt kommen wir der Sache näher! Du willst also gar kein Objekt zurückgeben, sondern bloß die Funktion, richtig?

                Ja.

                Dann gib kein Objekt {…} zurück, sondern direkt das Funktionsobjekt:

                Das macht Sinn! Jetzt funktioniert es.

                Jetzt stehe ich aber vor einer weiteren Herausforderung, ich dachte so geht's vielleicht, tut es aber nicht:

                var xyz = (function() {  
                  function init() {  
                  }  
                  
                  function privateMethod() {  
                  }  
                  
                  return function() {  
                    init();  
                    this.anotherPublicMethod = function() {  
                      privateMethod();  
                    }  
                  };  
                })();  
                  
                xyz(); // funktioniert  
                anotherPublicMethod(); // funktioniert nicht  
                
                

                Hast du hier noch einen Denkanstoss?

                vg ichbinich

                --
                Kleiner Tipp:
                Tofu schmeckt am besten, wenn man es kurz vor dem Servieren durch ein saftiges Steak ersetzt...
                1. xyz(); // funktioniert
                  anotherPublicMethod(); // funktioniert nicht

                  Sollte sogar beides gehen(ich sehe kein strict), aber das willst du nicht.
                  wenn du mehrere Funktionem raus geben musst, bleibt dir nur noch ein Objekt, an dem du dies speicherst.
                  Warum du aber keins zurückgeben willst, verstehe ich noch nicht ganz, bei einer Funktion war es dir ja auch egal, warum kein Objekt?

                  1. Hallo,

                    xyz(); // funktioniert
                    anotherPublicMethod(); // funktioniert nicht
                    Sollte sogar beides gehen(ich sehe kein strict), aber das willst du nicht.
                    wenn du mehrere Funktionem raus geben musst, bleibt dir nur noch ein Objekt, an dem du dies speicherst.
                    Warum du aber keins zurückgeben willst, verstehe ich noch nicht ganz, bei einer Funktion war es dir ja auch egal, warum kein Objekt?

                    Schwierige Vorgaben. Ist eigentlich keine sonderlich komplizierte Anwendung, wird aber später in eine App eingebunden in der auch Onlinebanking läuft. Und alles was dort eingebunden ist hat ganz strikte Vorgaben. Außerdem hängt da noch ein in der Firma selbstentwickeltes CMS dran und für das Einbinden dort sind nur 2 Aufrufe mit vordefinierten Namen möglich. Ersterer um die Anwendung normal aufzurufen und zweiterer, um innerhalb der Anwendung eine bestimmte Seite standalone aufzurufen. Anpassungen dort sind nicht vorgesehen (oder eher nicht gewünscht, ich hab mal einen Blick auf das CMS werfen können - da würde ich auch nichts anpassen wollen...).

                    D.h. also ich brauche den Aufruf xyz(). Soweit funktionierts ja schon. Nun brauche ich fürs CMS noch die zweite öffentliche Methode publicMethod().

                    vg ichbinich

                    --
                    Kleiner Tipp:
                    Tofu schmeckt am besten, wenn man es kurz vor dem Servieren durch ein saftiges Steak ersetzt...
                    1. Schwierige Vorgaben.

                      Ich würde mir die an deiner Stelle nochmal erklären lassen.

                      Nun brauche ich fürs CMS noch die zweite öffentliche Methode

                      wen du wirklich mehrere globale Methoden erstellen willst, kannst du das z.B. so machen

                        
                      (function(obj) {  
                        function init() {  
                        }  
                        
                        function privateMethod() {  
                        }  
                        
                        obj.init = init;  
                        obj.anotherPublicMethod = function() {  
                          privateMethod();  
                        }  
                      })(window);  
                      
                      ~~~.  
                      
                      
                2. Hallo,

                  Jetzt stehe ich aber vor einer weiteren Herausforderung, ich dachte so geht's vielleicht, tut es aber nicht:

                  Wir bewegen uns gerade einen Schritt vor und zwei Schritte zurück.

                  Du scheinst dir noch unklar darüber, was du genau willst, denn du formulierst widersprechende Anforderungen. Das Revealing Module Pattern ermöglicht dir private Variablen und gibt ein Objekt zurück, an das du mehrere Methoden hängen kannst.

                  Entscheide einmal, ob du ein Modul (Objekt) willst oder nur eine Funktion. Du kannst nicht beides gleichzeitig haben. Eine Funktion kann nur einen Wert zurückgeben. (Die Möglichkeit, an eine Funktion weitere Funktionen zu hängen, weil sie auch nur ein Objekt ist, lasse ich einmal außen vor. Das ist keine gute Coding-Praxis.)

                  Wenn du ein Objekt mit Methoden hast, dann kannst du diese nicht direkt mit methode1 und methode2 ansprechen, sondern musst objekt.methode1 bzw. objekt.methode2 schreiben. Du kannst, wenn es dir sinnvoll erscheint, natürlich eine weitere Variable auf die Funktion zeigen lassen.

                  var objekt = (function() {  
                    var methode = function() { alert(1); };  
                    return {  
                      methode: methode  
                    };  
                  })();  
                  objekt.methode(); // 1  
                  var f = objekt.methode; // Shortcut anlegen  
                  f(); // 1
                  

                  Das Anlegen dieser Shortcuts muss manuell passieren. Es ist nicht möglich und nicht sinnvoll, alle Methoden eines Objektes in den lokalen Scope zu importieren, sodass du direkt methode1(), methode() usw. ohne »objekt.« davor schreiben kannst.

                  Die unterschiedliche Aufrufweise wirkt sich übrigens auf die Bedeutung von this in der Funktion aus.

                  Vielleicht beschreibst du einmal, was du eigentlich vor hast, bevor wir uns hier weiter im Kreis drehen.

                  Mathias

                  1. Das Anlegen dieser Shortcuts muss manuell passieren. Es ist nicht möglich und nicht sinnvoll, alle Methoden eines Objektes in den lokalen Scope zu importieren, sodass du direkt methode1(), methode() usw. ohne »objekt.« davor schreiben kannst.

                    Es ist natürlich möglich, alle Methoden eines Objektes in den globalen Scope zu kopieren – das heißt sie zu Methoden vom globalen Objekt window zu machen.

                    var objekt = { // Oder ein Revealing Module, kommt auf dasselbe heraus  
                      foo: function() {},  
                      bar: function() {}  
                    };  
                    window.foo = objekt.foo;  
                    window.bar = objekt.bar;
                    

                    Automatisiert, erlaubt eine beliebige Anzahl von Eigenschaften:

                    [ref:self812;javascript/sprache/schleifen.htm#for@title=for] (var prop in objekt) {  
                      if (objekt.hasOwnProperty(prop)) { // Hier könnte man noch nach Funktionen filtern  
                        window[prop] = objekt[prop];  
                      }  
                    }
                    

                    Das kann natürlich bestehende globale Variablen/Funktionen überschreiben, deshalb vermeidet man das üblicherweise.

                  2. Hallo,

                    Entscheide einmal, ob du ein Modul (Objekt) willst oder nur eine Funktion. Du kannst nicht beides gleichzeitig haben. Eine Funktion kann nur einen Wert zurückgeben. (Die Möglichkeit, an eine Funktion weitere Funktionen zu hängen, weil sie auch nur ein Objekt ist, lasse ich einmal außen vor. Das ist keine gute Coding-Praxis.)

                    Wenn ich es so umsezten könnte wie ich will, würde ich ein Objekt zurückgeben und hätte die Methoden, die ich brauche. Ich hab aber feste Vorgaben, die ich nicht beeinflussen kann.

                    Vielleicht beschreibst du einmal, was du eigentlich vor hast, bevor wir uns hier weiter im Kreis drehen.

                    (s. hier)

                    vg ichbinich

                    --
                    Kleiner Tipp:
                    Tofu schmeckt am besten, wenn man es kurz vor dem Servieren durch ein saftiges Steak ersetzt...
  2. hi ichbinich,

    Hallo,

    var myfunc = (function() {

    [code lang=javascript]var myTestObjectReturnedByAnImmediateInvokedFunction = (function() {

      
    wäre "richtiger". myObj = tuts natürlich auch. Wichtig aber, es kommt ein Objekt zurück! Mit einer Methode in dem Fall.  
      
    mfg  
      
    tami