Felix Riesterer: seltsame (zumindest mir unbekannte) Syntax

Liebes Forum,

heute habe ich mir Struppis Javascript-Funktion "addEvent" heruntergeladen, da ich sehen wollte, was daran so besonders besser sein sollte, als an der Lösung, die ich bisher verwendet hatte.

Dabei bin ich über folgende Syntax gestolpert:

if (bedingung) {  
    ( function() { ... }() )  
}

Mir ist nicht klar, was die öffnende Klammer (ist das eine Parenthese?) unmittelbar for "function()" bedeutet, und warum sie dort steht. Ich hätte verstanden, wenn dort eine echte Funktionsdeklaration stünde, etwa wie function myFunc() { } oder aber auch myFunc = function () {}. Besonders verwirrend sind für mich die letzten Klammern unmittelbar vor dem Schließen des Anweisungsblocks.

Soll das ganze eine gigantische anonyme Funktion sein, die in sich neue Funktionen definiert?

Liebe Grüße aus Ellwangen,

Felix Riesterer.

  1. Moin!

    Keine Ahnung, ob es stimmt, aber für mich sieht das aus wie eine anonyme funktion die direkt ausgeführt wird.

    -- Skeeve

    1. Hallo Skeeve.

      Bitte keine Nullzitate, da man so den Postings schlecht folgen kann.

      Dabei bin ich über folgende Syntax gestolpert:

      if (bedingung) {

      ( function() { ... }() )
      }

      
      > >   
      > > Mir ist nicht klar, was die öffnende Klammer (ist das eine Parenthese?) unmittelbar for "function()" bedeutet, und warum sie dort steht.  
        
      
      > Keine Ahnung, ob es stimmt, aber für mich sieht das aus wie eine anonyme funktion die direkt ausgeführt wird.  
        
      Ganz genau.  
        
      function() {} ohne Namen gibt immer das Funktionsobjekt zurück. Dieses wird in obigem Codeschnipsel eingekapselt (was Felix im Übrigen falsch zitiert hat) und schließlich mit Hilfe des bekannten Klammernpaares ausgeführt.  
        
      Eigentlich sieht es so aus:  
        
      `( function() {} )()`{:.language-javascript}  
        
        
      Einen schönen Montag noch.  
        
      Gruß, Mathias  
      
      -- 
      sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|  
        
      debian/rules
      
      1. Ganz genau.

        function() {} ohne Namen gibt immer das Funktionsobjekt zurück. Dieses wird in obigem Codeschnipsel eingekapselt (was Felix im Übrigen falsch zitiert hat)

        hat er nicht.
        Wenn ich mich recht entsinne, ist es so

          
        if(typeof addEvent != 'undefined')  
        {  
            ( function() { ... } () );  
        }  
        
        

        Ist nicht ganz schön und teilweise zusammengeklaut aus den Vorschlägen http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html

        Struppi.

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

          function() {} ohne Namen gibt immer das Funktionsobjekt zurück. Dieses wird in obigem Codeschnipsel eingekapselt (was Felix im Übrigen falsch zitiert hat)

          hat er nicht.
          Wenn ich mich recht entsinne, ist es so

          if(typeof addEvent != 'undefined')
          {
              ( function() { ... } () );
          }

            
          Ahja, stimmt. Über die lange Distanz meinte ich, [diese Variante](http://jeenaparadies.net/weblog/2006/jan/zufallsheader#c1538) wiedererkannt zu haben.  
            
            
          Einen schönen Montag noch.  
            
          Gruß, Mathias  
          
          -- 
          sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|  
            
          debian/rules
          
        2. Lieber Struppi,

          Wenn ich mich recht entsinne, ist es so

          if(typeof addEvent != 'undefined')
          {
              ( function() { ... } () );
          }

            
          ich erkenne es wieder. Aber worin ist denn nun der Unterschied zwischen  
            
          `( function () {...} () );`{:.language-javascript}  
            
          und  
            
          `( function () {...} ) ();`{:.language-javascript}  
            
          zu sehen? Ich habe nun [molilys Artikel](http://aktuell.de.selfhtml.org/artikel/javascript/organisation/) gelesen und in etwa verstanden, dass es sich hier um eine Art Closure handelt.  
            
          Liebe Grüße aus [Ellwangen](http://www.ellwangen.de/),  
            
          Felix Riesterer.
          
          1. ich erkenne es wieder. Aber worin ist denn nun der Unterschied zwischen

            ( function () {...} () );

            und

            ( function () {...} ) ();

            Für mich ist da keiner, da wird wohl Mathias weiter Wissen
            Das zweite ist aber IMHO etwas logischer, du klammerst die anonyme Funktionsreferenz und rufst sie explizit durch die Parameterklammern auf. werd ich in Zukunft wohl eher verwenden.

            Struppi.

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

            Aber worin ist denn nun der Unterschied zwischen

            ( function () {...} () );

            und

            ( function () {...} ) ();

            Dagibt es keinen Unterschied, wobei ich persönlich die zweite Variante verwenden würde und auch logischer finde.

            Ich habe nun molilys Artikel gelesen und in etwa verstanden, dass es sich hier um eine Art Closure handelt.

            »Closure« bezeichnet eine bestimmte Eigenart von verschachtelten Funktionen.

            Die Verwendung von Closures ist der letztliche Zweck der ganzen Konstruktion, aber die anonyme Funktion, um die es hier geht, ist selbst nicht in einer anderen Funktion geschachtelt und wirkt daher nicht als Closure.

            Struppi verwendet diese Konstruktion, um gewisse Variablen mehreren Funktionen zur Verfügung zu stellen, ohne dass diese Variablen global sind:

            (function () {  
               var a, b, c;  
               window.f1 = function () {  
                  ...  
               };  
               window.f2 = function () {  
                  ...  
               };  
               ...  
            }();
            

            a, b und c sind nicht global verfügbar, aber für die globalen Methoden f1 und f2 und andere, auf ähnliche Weise notierte Methoden. Das liegt daran, dass f1 und f2 als Closure wirken und a, b und c einschließen. So können f1, f2 und ähnlich notierte Methoden diese Variablen gemeinsam benutzen, ohne dass sie global sein müssen.

            Man könnte genauso gut schreiben:

            function initAddEventScript () {  
               var a, b, c  
               f = function () {  
                  ...  
               };  
            }  
            initAddEventScript();
            

            Aber dann hätte man eine globale Funktion initAddEventScript, die man eigentlich gar nicht braucht, weil sie nur einmal ausgeführt wird und als Container für die Variablen-Mitbenutzung der darin notierten Funktionen fungiert. Daher benutzt man eine anonyme Funktion, die man sofort ausführt.

            Mathias

            --
            »No nations, no borders.«
            SELFHTML Weblog
  2. echo $begrüßung;

    Dabei bin ich über folgende Syntax gestolpert:

    Ich glaube, deine Fragen hat molily kürzlich in seinem Artikel Organisation von JavaScripten beantwortet.

    echo "$verabschiedung $name";

    1. Lieber dedlfix,

      Ich glaube, deine Fragen hat molily kürzlich in seinem Artikel Organisation von JavaScripten beantwortet.

      AHA! Das bringt schon ein ganzes Stückchen mehr Licht ins Dunkel. Es handelt sich hier offensichtlich um eine Closure...

      Liebe Grüße aus Ellwangen,

      Felix Riesterer.

  3. Hallo,

    if (bedingung) {

    ( function() { ... }() )
    }

    
    >   
    > Mir ist nicht klar, was die öffnende Klammer (ist das eine Parenthese?) unmittelbar for "function()" bedeutet, und warum sie dort steht.  
      
    function () {} (); würde einen Syntaxfehler geben, entweder muss die Funktion-Expression oder der ganze Ausdruck geklammert werden (kann ich nicht auf Parsingebene erklären - ist halt so).  
      
    
    > Ich hätte verstanden, wenn dort eine echte Funktionsdeklaration stünde, etwa wie `function myFunc() { }`{:.language-javascript} oder aber auch `myFunc = function () {}`{:.language-javascript}.  
      
    Nur function func () { ... } außerhalb eines anderen Statements ist eine echte Funktionsdeklaration (»function deklaration«).  
      
    func = function () {}; ist syntaktisch etwas ganz anderes.  
      
    1\. Es ist ein Expression Statement,  
     2. bestehend aus einer Assignment Expression,  
      3.1 bestehend auf der linken Seite von = mit einem Identifier,  
      3.2 bestehend auf der rechten Seite von = mit einer Function Expression.  
      
    Ausdrücke (Expressions) können in ECMAScript an sehr vielen Stellen vorkommen. In ECMAScript ist vieles ein Ausdruck, was in anderen Sprachen ein Statement ist. Darunter gibt es Function-Expressions (»Funktionsausdrücke«), die für sich wie gesagt einfach ein Funktionsobjekt zurückgeben, ohne das irgendwo zu speichern.  
      
    Der Ausdruck »(function () {}) ()« wird wie bei ein mathematischer Term aufgelöst. Der erste geklammerte Teil mit der Function-Expression ein Funktionsobjekt. Darauf wird dann der sogenannte Call-Operator angewendet, das sind die Klammern mit der (hier leeren) Parameterliste.  
      
    Übrigens kann man auch func = function bla () {}; schreiben, das ist dann immer noch eine Function-Expression, der Name »bla« hat also keinen Effekt. Deshalb schrieb ich oben »außerhalb eines anderen Statements«. Ohne Kontext kann man nicht beurteilen, ob function func () { ... } eine Declaration oder eine Expression ist.  
      
    Mathias
    
    -- 
    »No nations, no borders.«  
    [SELFHTML Weblog](http://aktuell.de.selfhtml.org/weblog/)