Frage

Ich habe einige Beiträge über Schließungen zu lesen und sah dies überall, aber es gibt keine klare Erklärung, wie es funktioniert - jedes Mal war ich gerade gesagt, es zu benutzen ...:

// 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 neue anonyme Funktion erstellen und dann ausführen. So nach, dass dieser einfache Code funktionieren soll (und es tut):

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

Meine Frage ist, welche Art von Magie geschieht hier? Ich dachte, dass, wenn ich schrieb:

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

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

aber warum dann tut das nicht?

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

Warum braucht man es in der gleichen Linie sein?

Könnten Sie mir bitte einige Beiträge zeigen oder eine Erklärung geben Sie mir?

War es hilfreich?

Lösung

Lassen Sie das Semikolon nach der Funktionsdefinition.

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

Vor sollte funktionieren.

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

ich diese Art von Muster in diesem Beitrag diskutiert habe:

jQuery und $ Fragen

EDIT:

Wenn man sich ECMA-Script-Spezifikation gibt es 3 Möglichkeiten, wie Sie eine Funktion definieren können. (Seite 98, Kapitel 13 Funktions Definition)

1. Mit Funktion Konstruktor

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

2. Mit Funktionsdeklaration.

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

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

3. Funktion Expression

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

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

So können Sie fragen, was ist der Unterschied zwischen Erklärung und Ausdruck?

Von ECMA Script-Spezifikation:

  

FunctionDeclaration:       Funktionskennung (FormalParameterListopt) {FunctionBody   }

     

FunctionExpression:       funktionieren Identifieropt (FormalParameterListopt) {FunctionBody   }

Wenn Sie bemerken, 'Bezeichner' ist optional für Funktionsausdruck. Und wenn Sie nicht eine Kennung geben, erstellen Sie eine anonyme Funktion. Es bedeutet nicht, dass Sie nicht eine Kennung angeben.

Das bedeutet, gilt folgendes.

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

Wichtiger Punkt zu beachten ist, dass Sie mySum 'können nur innerhalb des mySum Funktion Körper, 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 wollen wir versuchen, den Code zu analysieren.

Wenn Sie Code wie,

    function(msg) { alert(msg); }

Sie haben einen Funktionsausdruck. Und Sie können diese Funktion Ausdruck ausführen, indem sie in Klammern gewickelt wird.

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

Andere Tipps

Es ist eine Selbst aufgerufen Funktion aufgerufen.

Was Sie tun, wenn Sie (function(){}) rufen ein Funktionsobjekt zurückkehrt. Wenn Sie () ihm anhängen, wird sie aufgerufen und alles, was im Körper ausgeführt wird. Die ; bezeichnet das Ende der Anweisung, das ist, warum der zweite Aufruf fehlschlägt.

Eine Sache, die ich verwirrend fand ist, dass die „()“ gruppieren Operatoren.

Hier ist Ihre grundlegende Funktion erklärt.

Ex. 1:

var message = 'SO';

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

foo(message);

Funktionen sind Objekte und können gruppiert werden. Also lassen Sie uns Pars werfen um die Funktion.

Ex. 2:

var message = 'SO';

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

(foo)(message);     // calls foo

Jetzt statt erklärt und rechts entfernt die gleiche Funktion aufrufen, können wir grundlegende Substitution verwenden, es zu erklären, wie wir es nennen.

Ex. 3.

var message = 'SO';

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

Schließlich haben wir keinen Bedarf für die zusätzlich foo haben, weil wir nicht den Namen verwenden es zu nennen! Funktionen können anonym.

Ex. 4.

var message = 'SO';

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

Um Ihre Frage zu beantworten, verweist auf Beispiel 2. Ihre erste Zeile deklariert einige namenlos Funktion und Gruppen, aber es nicht nennen. Die zweiten Leitungsgruppen eine Zeichenfolge. Beide tun nichts. (Vincent erstes Beispiel.)

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

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

Aber

(foo)
(msg); //works

Eine anonyme Funktion ist keine Funktion mit dem Namen „“. Es ist einfach eine Funktion ohne Namen.

Wie bei jedem anderen Wert in JavaScript, um eine Funktion braucht keinen Namen erstellt werden. Obwohl es viel nützlicher, um tatsächlich binden Sie es an einem Namen wie jeder andere Wert ist.

Aber wie jeder andere Wert, Sie möchten manchmal, es zu benutzen, ohne es zu einem Namen zu binden. Das ist die Selbst Aufruf-Muster.

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

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

So haben wir sie in einer Variablen speichern zu können, sie benutzen, genau wie jeder andere Wert:

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

Sie können auch syntaktischen Zucker zu binden, um die Funktion einer Variablen verwenden:

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

Aber wenn sie zu benennen ist nicht erforderlich und würde zu mehr Verwirrung und weniger Lesbarkeit führen, man kann sich nur sofort verwenden.

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

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

wie dies sagte, es sieht aus wie selbst Aufruf Funktion keinen realen Wert hat. Aber Sie müssen bedenken, dass JavaScript Umfang Begrenzer die Funktion und nicht der Block ({}).

So ein Selbst Aufruf Funktion hat tatsächlich die gleiche Bedeutung wie C ++, C # oder Java-Block. Was bedeutet, dass Variable innerhalb erstellt wird außerhalb des Bereichs nicht „Leck“. Dies ist sehr nützlich in JavaScript, um nicht den globalen Bereich zu verschmutzen.

Es ist nur so, wie JavaScript funktioniert. Sie können eine benannte Funktion deklarieren:

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

Und nennen es:

foo("Hi!");

Alternativ können Sie eine anonyme Funktion deklarieren:

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

Und nennt das:

foo("Hi!");

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

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

Funktionen können auch Funktionen zurück:

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

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

Es ist nichts wert, dass alle Variablen mit „var“ definiert im Körper make_foo durch jede Funktion von make_foo zurückgegeben wird geschlossen über. Dies ist ein Verschluss, und es bedeutet, dass die durch eine Änderung einer Funktion auf den Wert gemacht wird durch eine andere sichtbar.

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

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

var hello = make_greeter("Hello!");

hello();

Es ist nur so, wie fast jeder Programmiersprache Java, aber funktioniert.

Der Code, den Sie zeigen,

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

bestehen aus zwei Aussagen. Der erste ist ein Ausdruck, der ein Funktionsobjekt ergibt (der dann Müll gesammelt werden, weil sie nicht gespeichert ist). Die zweite ist ein Ausdruck, der eine Zeichenfolge ergibt. Um die Funktion auf den String anwenden, müssen Sie entweder die Zeichenfolge als Argument an die Funktion zu übergeben, wenn es erstellt wird (die man auch oben zeigen), oder müssen Sie tatsächlich speichern Sie die Funktion in einer Variablen, so dass Sie wenden sie es zu einem späteren Zeitpunkt, in Ihrer Freizeit. Wie so:

var f = (function (msg){alert(msg)});
f('SO');

Beachten Sie, dass durch eine anonyme Funktion Speicher (eine Lambda-Funktion) in einer Variablen, Sie werden ihm einen Namen effektiv zu geben. Daher können Sie genauso gut eine reguläre Funktion definieren:

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

In Zusammenfassung der vorherigen Kommentare:

function() {
  alert("hello");
}();

, wenn sie nicht an eine Variable zugeordnet, ergibt einen Syntaxfehler. Der Code wird als Funktion Anweisung (oder Definition) analysiert, die die Schließ Klammern syntaktisch falsch macht. Hinzufügen von Klammern um den Funktionsabschnitt teilt den Interpreter (und Programmierer), dass dies ein Funktionsausdruck (oder Aufruf), wie in

(function() {
  alert("hello");
})();

Dies ist eine selbst Aufruf Funktion, dh es anonym erstellt und läuft sofort, weil der Aufruf in der gleichen Zeile geschieht, wo sie deklariert ist. Diese Selbst rufenden Funktion wird mit der bekannten Syntax zeigt eine nicht-Argument Funktion aufzurufen, und hinzugefügt Klammern um den Namen der Funktion. (myFunction)();

Es gibt eine gute SO Diskussion JavaScript Funktion Syntax .

Diese Antwort streng ist nicht auf die Frage bezogen, aber Sie könnten, um herauszufinden, interessiert sein, dass diese Art von Syntax-Funktion nicht besonders an Funktionen ist. Zum Beispiel können wir so etwas wie dies immer tun:

alert(
    {foo: "I am foo", bar: "I am bar"}.foo
); // alerts "I am foo"

auf Funktionen Verwandte. Als sie Objekte, die von Function.prototype erben, können wir Dinge tun, wie:

Function.prototype.foo = function () {
    return function () {
        alert("foo");
    };
};

var bar = (function () {}).foo();

bar(); // alerts foo

Und Sie wissen, wir haben nicht einmal Funktionen umgeben mit Klammern, um sie auszuführen. Wie auch immer, solange wir versuchen, das Ergebnis einer Variablen zugewiesen werden soll.

var x = function () {} (); // this function is executed but does nothing

function () {} (); // syntax error

Eine andere Sache, die Sie mit Funktionen tun können, sobald Sie sie erklären, ist die new Betreiber über sie aufzurufen und ein Objekt zu erhalten. Die folgenden sind äquivalent:

var obj = new function () {
    this.foo = "bar";
};

var obj = {
    foo : "bar"
};

Es gibt eine weitere Eigenschaft JavaScript-Funktion. Wenn Sie möchten, rekursiv gleiche anonyme Funktion aufzurufen.

(function forInternalOnly(){

  //you can use forInternalOnly to call this anonymous function
  /// forInternalOnly can be used inside function only, like
  var result = forInternalOnly();
})();

//this will not work
forInternalOnly();// no such a method exist

Mein Verständnis der Frage des Fragestellers ist so, dass:

Wie funktioniert diese magische Arbeit:

(function(){}) ('input')   // Used in his example

Ich kann mich irren. Allerdings ist die übliche Praxis, dass die Menschen vertraut sind ist:

(function(){}('input') )

Der Grund dafür ist, dass JavaScript AKA () Klammer, kann keine Aussagen enthalten und wenn der Parser die Funktion Schlüsselwort trifft, weiß er es als Funktion Ausdruck zu analysieren und nicht eine Funktion Erklärung an.

Quelle: Blog-Post Sofort-Ausgeführt Funktion Ausdruck ( IIFE)

Beispiele ohne Klammern:

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

(dies ist die einzige wirkliche Verwendung von Leere, afaik)

oder

var a = function (msg) { alert(msg); }
('SO');

oder

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

Arbeit als gut. die void verursacht die Expression sowie die Zuordnung und den Knall zu bewerten. die letzte arbeitet mit ~, +, -, delete, typeof, (ist void man auch) einige der unäre Operatoren. nicht arbeiten, sind von couse ++, -- wegen des Erfordernisses einer Variablen.

der Zeilenumbruch ist nicht erforderlich.

Es ist eine selbstausführende anonyme Funktion. Der erste Satz von Klammern enthält die Ausdrücke ausgeführt werden, und der zweite Satz von Klammern führt diese Ausdrücke.

(function () {
    return ( 10 + 20 );
})();

Peter Michaux bespricht den Unterschied in der .

Es ist ein nützliches Konstrukt, wenn sie versuchen Variablen aus dem übergeordneten Namensraum zu verstecken. Die gesamte Code innerhalb der Funktion ist im privaten Rahmen der Funktion enthalten, was bedeutet, es kann gar nicht von außerhalb der Funktion zugegriffen werden, so dass es wirklich privat.

Siehe auch:

  1. Closure (Informatik)
  2. JavaScript Namensräumen
  3. Wichtiges Paar Javascript Klammerung

Ein weiterer Gesichtspunkt

Sie können zunächst eine anonyme Funktion deklarieren:

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

Dann rufen Sie es:

foo ('Few');

Da foo = function (msg) {alert (msg);} , so dass Sie ersetzen foo wie:

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

Aber Sie sollten Ihre gesamte anonyme Funktion innerhalb Paar Klammern wickeln Syntaxfehler zu vermeiden Funktion zu erklären, wenn das Parsen. Dann haben wir,

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

Auf diese Weise ist es einfach für mich verstehen.

Wenn Sie getan haben:

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

Sie beendet die Funktion vor ('SO') wegen des Semikolon. Wenn Sie nur schreiben:

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

Es wird funktionieren.

Arbeitsbeispiel: http://jsfiddle.net/oliverni/dbVjg/

Der einfache Grund, warum es nicht funktioniert, ist nicht wegen der ; das Ende der anonymen Funktion angibt. Es ist, weil ohne die () am Ende eines Funktionsaufrufs, ist es nicht ein Funktionsaufruf ist. Das heißt,

function help() {return true;}

Wenn Sie result = help(); nennen dies ist ein Aufruf an eine Funktion und gibt true zurück.

Wenn Sie result = help; nennen, ist dies kein Anruf. Es ist eine Zuordnung, wo Hilfe behandelt wird, wie Daten zu führen, zugeordnet werden.

Was du getan hast wurde erklärt / eine anonyme Funktion instanziieren durch das Semikolon,

(function (msg) { /* Code here */ });

und dann versucht, es in einer anderen Anweisung aufgerufen wird, indem nur Klammern mit ... Offensichtlich, weil die Funktion keinen Namen hat, aber das wird nicht funktionieren:

('SO');

Der Interpreter sieht die Klammern in der zweiten Zeile als neue Befehl / Anweisung, und somit ist es nicht funktioniert, auch wenn Sie es so taten:

(function (msg){/*code here*/});('SO');

Es funktioniert immer noch nicht, aber es funktioniert, wenn Sie das Semikolon entfernen, weil der Dolmetscher weiße Flächen und Wagen ignoriert und sieht den vollständigen Code als eine Anweisung.

(function (msg){/*code here*/})        // This space is ignored by the interpreter
('SO');

Fazit: ein Funktionsaufruf ist kein Funktionsaufruf ohne () am Ende, es sei denn unter bestimmten Bedingungen, wie durch eine andere Funktion aufgerufen wird, das heißt, onload = ‚Hilfe‘ die Hilfe-Funktion selbst würde ausführen, obwohl die Klammern waren nicht inbegriffen. Ich glaube, setTimeout und setInterval auch zu dieser Art des Funktionsaufrufes erlauben, und ich glaube auch, dass die Dolmetscher die Klammern hinter den Kulissen fügen sowieso, die uns zurück zu bringen „ein Funktionsaufruf ist kein Funktionsaufruf ohne Klammern“.

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

Dies ist eine gängige Methode, um eine anonyme Funktion als Verschluss zu verwenden, die viele JavaScript-Frameworks verwenden.

Diese Funktion wird automatisch aufgerufen, wenn der Code kompiliert wird.

Wenn ; in der ersten Zeile platzieren, der Compiler behandelt sie als zwei verschiedene Linien. So können Sie nicht die gleichen Ergebnisse wie oben erhalten.

Dies kann auch wie folgt geschrieben werden:

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

Für weitere Details schauen Sie in JavaScript / Anonyme Funktionen .

  1. Anonyme Funktionen sind Funktionen, die dynamisch deklariert sind bei Laufzeit. Sie sind anonyme Funktionen genannt, weil sie nicht einen Namen in der gleichen Weise wie normale Funktionen gegeben.

    Anonyme Funktionen werden über die Funktion Operator stattdessen erklärt die Funktionsdeklaration. Sie können die Funktion Operator verwenden, um Erstellen Sie eine neue Funktion, wo immer sie gültig ist, einen Ausdruck zu bringen. Zum Beispiel könnten Sie eine neue Funktion als Parameter an einem deklarieren Funktionsaufruf oder eine Eigenschaft eines anderen Objekts zugeordnet werden.

    Hier ist ein typisches Beispiel für eine benannte Funktion:

    Funktion flyToTheMoon () {alert ( "Zoom Zoom Zoom!"); } zum Mond fliegen(); Hier ist das gleiche Beispiel wie eine anonyme erstellt Funktion:

    var flyToTheMoon = function () {alert ( "Zoom Zoom Zoom!"); } flyToTheMoon ();

    Für Details lesen Sie bitte hier:

    http://helephant.com/2008/08/23/javascript -Anonymous-Funktionen /

Die IIFE compartmentalizes einfach die Funktion und blendet die msg Variable, um nicht den globalen Namensraum „verschmutzen“. In Wirklichkeit hält sie nur einfach und tut wie unten, wenn Sie eine Milliarden-Dollar-Website bauen.

var msg = "later dude";
window.onunload = function(msg){
  alert( msg );
};

Sie können Ihre Namespace msg Eigenschaft mit einem Aufdecken Module Muster wie:

var myScript = (function() {
    var pub = {};
    //myscript.msg
    pub.msg = "later dude";
    window.onunload = function(msg) {
        alert(msg);
    };
    //API
    return pub;
}());

Anonyme Funktionen sollen One-Shot-Deal sein, wo Sie eine Funktion im laufenden Betrieb definieren, so dass es eine Ausgabe von Ihnen von einem Eingang erzeugt, die Sie bereitstellen. Abgesehen davon, dass Sie die Eingabe nicht vorsah. Stattdessen schrieb sie etwas in der zweiten Zeile ( ‚SO‘); - eine unabhängige Aussage, die nichts mit der Funktion zu tun hat. Was hast du erwartet? :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top