391 Stimmen

Warum müssen Sie eine anonyme Funktion in der gleichen Zeile aufrufen?

Ich habe einige Beiträge über Verschlüsse gelesen und dies überall gesehen, aber es gibt keine klare Erklärung, wie es funktioniert - jedes Mal wurde mir nur gesagt, dass ich es benutzen soll...:

// Create a new anonymous function, to use as a wrapper
(function(){
    // The variable that would, normally, be global
    var msg = "Thanks for visiting!";

    // Binding a new function to a global object
    window.onunload = function(){
        // Which uses the 'hidden' variable
        alert( msg );
    };
// Close off the anonymous function and execute it
})();

Ok, ich sehe, dass wir eine neue anonyme Funktion erstellen und diese dann ausführen werden. Danach sollte dieser einfache Code also funktionieren (und das tut er auch):

(function (msg){alert(msg)})('SO');

Meine Frage ist: Welche Art von Magie geschieht hier? Das dachte ich, als ich schrieb:

(function (msg){alert(msg)})

dann würde eine neue unbenannte Funktion wie function ""(msg) ... erstellt werden.

aber warum funktioniert das dann nicht?

(function (msg){alert(msg)});
('SO');

Warum muss sie in der gleichen Zeile stehen?

Könnten Sie mir bitte einige Stellen nennen oder mir eine Erklärung geben?

384voto

SolutionYogi Punkte 30824

Lassen Sie das Semikolon nach der Funktionsdefinition weg.

(function (msg){alert(msg)})
('SO');

Oben sollte funktionieren.

DEMO-Seite: https://jsfiddle.net/e7ooeq6m/

Ich habe diese Art von Muster in diesem Beitrag besprochen:

jQuery und $ Fragen

EDIT :

Wenn Sie sich ECMA-Skript-Spezifikation Es gibt 3 Möglichkeiten, eine Funktion zu definieren. (Seite 98, Abschnitt 13 Funktionsdefinition)

1. Verwendung des Funktionskonstruktors

var sum = new Function('a','b', 'return a + b;');
alert(sum(10, 20)); //alerts 30

2. Funktionsdeklaration verwenden.

function sum(a, b)
{
    return a + b;
}

alert(sum(10, 10)); //Alerts 20;

3. Funktion Ausdruck

var sum = function(a, b) { return a + b; }

alert(sum(5, 5)); // alerts 10

Sie fragen sich vielleicht, was der Unterschied zwischen Erklärung und Ausdruck ist?

Aus der ECMA-Script-Spezifikation:

F Funktion Bezeichner ( FormalParameterListopt ){ FunctionBody }

F f }

Wie Sie feststellen können, ist 'identifier' optional für Funktionsausdruck. Und wenn Sie keinen Bezeichner angeben, erstellen Sie eine anonyme Funktion. Das heißt aber nicht, dass Sie keinen Bezeichner angeben können.

Dies bedeutet, dass Folgendes gültig ist.

var sum = function mySum(a, b) { return a + b; }

Wichtig ist, dass Sie "mySum" nur innerhalb des mySum-Funktionskörpers verwenden können, nicht außerhalb. Siehe folgendes Beispiel:

var test1 = function test2() { alert(typeof test2); }

alert(typeof(test2)); //alerts 'undefined', surprise! 

test1(); //alerts 'function' because test2 is a function.

Live-Demo

Vergleichen Sie dies mit

 function test1() { alert(typeof test1) };

 alert(typeof test1); //alerts 'function'

 test1(); //alerts 'function'

Mit diesem Wissen bewaffnet, wollen wir nun versuchen, Ihren Code zu analysieren.

Wenn Sie einen Code wie,

    function(msg) { alert(msg); }

Sie haben einen Funktionsausdruck erstellt. Und Sie können diesen Funktionsausdruck ausführen, indem Sie ihn in Klammern einschließen.

    (function(msg) { alert(msg); })('SO'); //alerts SO.

133voto

seth Punkte 35911

Das nennt man eine selbst herbeigeführte Funktion.

Was Sie tun, wenn Sie anrufen (function(){}) ist die Rückgabe eines Funktionsobjekts. Wenn Sie an () aufruft, wird er aufgerufen und alles, was im Body steht, wird ausgeführt. Die ; das Ende der Anweisung bezeichnet, weshalb der 2. Aufruf fehlschlägt.

94voto

Benxamin Punkte 4646

Eine Sache, die ich verwirrend fand, ist, dass die "()" Gruppierungsoperatoren sind.

Hier ist Ihre erklärte Grundfunktion.

Bsp. 1:

var message = 'SO';

function foo(msg) {
    alert(msg);
}

foo(message);

Funktionen sind Objekte, die gruppiert werden können. Lassen Sie uns also Parens um die Funktion setzen.

Bsp. 2:

var message = 'SO';

function foo(msg) {  //declares foo
    alert(msg);
}

(foo)(message);     // calls foo

Anstatt dieselbe Funktion zu deklarieren und gleich wieder aufzurufen, können wir sie nun mit Hilfe der einfachen Substitution deklarieren, während wir sie aufrufen.

Bsp. 3.

var message = 'SO';

(function foo(msg) {
    alert(msg);
})(message);          // declares & calls foo

Schließlich brauchen wir das zusätzliche foo nicht, weil wir den Namen nicht verwenden, um es zu nennen! Funktionen können anonym sein.

Ex. 4.

var message = 'SO';

(function (msg) {   // remove unnecessary reference to foo
    alert(msg);
})(message);

Um Ihre Frage zu beantworten, gehen Sie zurück zu Beispiel 2. Ihre erste Zeile deklariert eine namenlose Funktion und gruppiert sie, ruft sie aber nicht auf. Die zweite Zeile gruppiert eine Zeichenkette. Beide tun nichts. (Das erste Beispiel von Vincent.)

(function (msg){alert(msg)});  
('SO');                       // nothing.

(foo); 
(msg); //Still nothing.

Mais

(foo)
(msg); //works

24voto

Vincent Robert Punkte 34478

Eine anonyme Funktion ist keine Funktion mit dem Namen "". Es handelt sich einfach um eine Funktion ohne Namen.

Wie jeder andere Wert in JavaScript braucht auch eine Funktion keinen Namen, um erstellt zu werden. Es ist jedoch viel nützlicher, sie wie jeden anderen Wert an einen Namen zu binden.

Aber wie bei jedem anderen Wert auch, möchte man ihn manchmal verwenden, ohne ihn an einen Namen zu binden. Das ist das selbstaufrufende Muster.

Hier sind eine Funktion und eine Zahl nicht gebunden, sie tun nichts und können nie verwendet werden:

function(){ alert("plop"); }
2;

Wir müssen sie also in einer Variablen speichern, um sie wie jeden anderen Wert verwenden zu können:

var f = function(){ alert("plop"); }
var n = 2;

Sie können auch syntaktischen Zucker verwenden, um die Funktion an eine Variable zu binden:

function f(){ alert("plop"); }
var n = 2;

Wenn die Benennung jedoch nicht erforderlich ist und zu mehr Verwirrung und schlechterer Lesbarkeit führen würde, können Sie sie einfach sofort verwenden.

(function(){ alert("plop"); })(); // will display "plop"
alert(2 + 3); // will display 5

Hier sind meine Funktion und meine Zahlen nicht an eine Variable gebunden, aber sie können trotzdem verwendet werden.

So gesagt, sieht es so aus, als ob die selbstaufrufende Funktion keinen wirklichen Wert hat. Aber Sie müssen im Auge behalten, dass JavaScript Bereich Begrenzer ist die Funktion und nicht der Block ({}).

Eine sich selbst aufrufende Funktion hat also die gleiche Bedeutung wie ein C++-, C#- oder Java-Block. Das bedeutet, dass eine darin erstellte Variable nicht außerhalb des Geltungsbereichs "auslaufen" kann. Dies ist in JavaScript sehr nützlich, um den globalen Bereich nicht zu verschmutzen.

19voto

jrockway Punkte 40754

So funktioniert JavaScript nun einmal. Sie können eine benannte Funktion deklarieren:

function foo(msg){
   alert(msg);
}

Und nennen Sie es:

foo("Hi!");

Oder Sie können eine anonyme Funktion deklarieren:

var foo = function (msg) {
    alert(msg);
}

Und nennen Sie das:

foo("Hi!");

Oder Sie können die Funktion einfach nie an einen Namen binden:

(function(msg){
   alert(msg);
 })("Hi!");

Funktionen können auch Funktionen zurückgeben:

function make_foo() {
    return function(msg){ alert(msg) };
}

(make_foo())("Hi!");

Es ist nichts wert, dass alle Variablen, die mit "var" im Textkörper von make_foo wird von jeder Funktion geschlossen, die von make_foo . Dies ist ein Abschluss und bedeutet, dass jede Änderung des Wertes durch eine Funktion für eine andere sichtbar ist.

Auf diese Weise können Sie Informationen kapseln, wenn Sie dies wünschen:

function make_greeter(msg){
    return function() { alert(msg) };
}

var hello = make_greeter("Hello!");

hello();

So funktioniert fast jede Programmiersprache außer Java.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X