2013-04-03 5 views
8

Was ist der Zweck der äußeren zusätzlichen Klammern auf die folgende JavaScript-Closure-Funktion? Mir wurde in anderen Beiträgen gesagt, dass sie nicht unbedingt notwendig sind, aber sie sind eine Konvention, um klarzustellen, dass das Ergebnis der Funktion übergeben wird, nicht die Funktion selbst. Das folgende Zitat aus http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html widerspricht jedoch. Welches ist richtig?Zweck der äußeren zusätzlichen Klammer auf JavaScript-Verschließfunktion

Beachten Sie die() um die anonyme Funktion. Dies wird von der Sprache verlangt, da Anweisungen, die mit der Token-Funktion beginnen, immer als Funktionsdeklarationen gelten. Include() erstellt stattdessen einen Funktionsausdruck.

(function() { 
    // ... all vars and functions are in this scope only 
    // still maintains access to all globals 
}()); 
+1

Sie es auch mit Void Präfix kann passieren oder einem arithmetischen Operator. –

+1

@Jack. Bitte melde dich. – user1032531

+1

http://benalman.com/news/2010/11/immediately-invoked-function-expression/ –

Antwort

5

Ich denke, dass verschiedene Motoren haben unterschiedliche Wege der Interpretation

function(){...}();

so die populärste und akzeptierte Art und Weise deutlich zu machen, für alle Motoren, zu einer Gruppe ist der Code in Klammern.

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

Zur gleichen Zeit, was Sie zitiert macht einen sehr interessanten Punkt. Ein Funktionsausdruck könnte gehen:

var f = function() {...}

Während eine Funktionsdeklaration wie folgt aussieht:

function f() {...}

Sie sehen, wie es ist einfach/günstig für die Parser den Unterschied zu erkennen, indem bei der ersten Suche Zeichen?

IF TOKEN1 EQ "function": FXN DECLARATION 
ELSE: FXN EXPRESSION 

Aber es wäre nicht sinnvoll für Ihre (sofort beschworene) Funktion machen eine Funktionsdeklaration zu sein (es ist nicht wiederverwendet werden würde, Sie wollen nicht haben es hochgezogen, oder in der Namespace usw.), so dass einige unschädliche Klammern hinzugefügt werden können, um darauf hinzuweisen, dass es sich um einen Funktionsausdruck handelt.

+0

Also ist es manchmal erforderlich und manchmal nicht auf der gegebenen Maschine basiert, und ich sollte es einfach die ganze Zeit tun? – user1032531

+1

Ja. Es ist eine sehr starke Konvention. Sie sollten es wahrscheinlich die ganze Zeit tun ... es sei denn, Sie finden eine andere beliebte Möglichkeit, es dem Motor klar zu machen, und wollen dafür eintreten. – ktm5124

+0

FF führt zu einem Syntaxfehler ohne es. – user1032531

1

Sie sind notwendig, weil der Parser im Modus Funktionsdeklaration geht, wenn es

function 

in einem Kontext Aussage sieht.

Nach Token function erwartet es einen Namen für die Funktion, da eine Funktionsdeklaration einen Namen für die Funktion enthalten muss. Aber anstelle eines Namens sieht es stattdessen (, also ist es ein Syntaxfehler.

Ich denke, es könnte zurückverfolgen und eindeutig behandeln es nur als eine Funktion Ausdruck, aber es tut es nicht.


var module = XXX

In dem obigen ist XXX in Ausdruck Kontext, wenn ein function erscheint, wird er als Beginn einer Funktion Ausdruck behandelt. Funktionsausdrücke müssen keinen Namen für die Funktion haben, daher ist es kein Syntaxfehler, ( direkt nach function erscheinen zu lassen.

So können Sie schreiben:

var module = function(){}(); 

Aber nicht

function(){}() 

können Sie viele Tricks anwenden, die über einen Ausdruck zu machen:

(XXX) 
!XXX 
~XXX 
+XXX 

//This doesn't work however: 
{YYY} //the braces are delimiting a block, and inside block you start in 
     //a statement context 

XXX ist in Ausdruck Kontext, weil es ist in Klammern eingeschlossen oder folgt einem unären Operator, also jeder Funktion ersetzt für XXX ist ein Funktionsausdruck.

3

Die zusätzlichen umgebenden Klammern unterscheiden einen Funktionsausdruck von einer regulären Funktionsdeklaration.

Obwohl die zusätzlichen Klammern gängige Praxis sind, kann die gleiche Sache, indem Sie diese stattdessen erreicht werden:

void function() { 
    // do stuff 
}(); 

Oder auch:

+function() { 
    // do stuff 
}(); 

Obwohl aus diesen beiden Alternativen, ich bevorzugen Sie die Notation void, weil wir uns in den meisten Fällen nicht wirklich um den Rückgabewert eines sofortigen Aufrufs kümmern.

Andere Orte, an denen die Klammern sind nicht erforderlich ist, wenn ein Ausdruck erwartet wird:

setTimeout(function() { 
    return function() { 
     alert('hello'); 
    } 
}(), 1000); 
4

Zunächst einmal muss ich klären:

(function() { 

}()); 

entspricht für

(function() { 

})(); 

und auch für (Backbone.js verwendet es)

(function(){ 

}).call(this); 

Zweitens, wenn Sie es so verwenden, dann ist es keine anonyme/Closure-Funktion. seine Sofort-Ausgeführt Funktion Ausdruck

es als Verschluss handeln würde (weil es nicht sofort beschworene sein wird), wenn Sie seine zurück Kontext einer Variablen zuweisen. Dies ist nützlich, wenn Sie eine statische Klasse benötigen (wenn auf Eigenschaften und Methoden ohne Instanziierung zugegriffen werden kann).Zum Beispiel:

var stuff = (function(){ 

    // AGAIN: its not an IIFE in this case 

    function foo() // <- public method 
    { 
     alert('Jeeez'); 
    } 

    return { 
     foo : foo, 
    } 
})(); 


stuff.foo(); //Alerts Jeeez 

Was ist der Zweck der äußeren zusätzlichen Klammern auf der unten JavaScript Verschlussfunktion?

Der Zweck ist nicht üblich und ziemlich seltsam - es ist alles über Funktionsargumente. Zum Beispiel

(function(window, document){ // <- you see this? 2 "arguments" 

    alert(arguments.length); // 0! 

})(); 

aber wenn wir sie an, dass die äußere Klammern

(function(/* So its not for arguments */){ 

    alert(arguments.length); // 2 

})(window, document); // <- Instead we pass arguments here 
+2

Große Erklärung. Ich wünschte, ich könnte mehr wählen. Ich glaube, dass andere Antworten meiner spezifischen Frage besser entsprachen, aber das klärte ein größeres Geheimnis von mir auf. '(function (c, d) {console.log (a, b, c, d);} (a, b));' wird a, b, a, b anzeigen. Ich verstehe es dank dir! Vielen Dank – user1032531

Verwandte Themen