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?

8voto

Stephan202 Punkte 57491

Der von Ihnen gezeigte Code,

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

bestehen aus dos Erklärungen. Die erste ist ein Ausdruck, der ein Funktionsobjekt ergibt (das dann gelöscht wird, da es nicht gespeichert wird). Die zweite ist ein Ausdruck, der eine Zeichenkette ergibt. Um die Funktion auf die Zeichenkette anzuwenden, müssen Sie entweder die Zeichenkette als Argument an die Funktion übergeben, wenn diese erstellt wird (was Sie oben auch zeigen), oder Sie müssen die Funktion in einer Variablen speichern, damit Sie sie später in aller Ruhe anwenden können. Zum Beispiel so:

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

Beachten Sie, dass Sie einer anonymen Funktion (einer Lambda-Funktion) einen Namen geben, indem Sie sie in einer Variablen speichern. Sie können also genauso gut eine reguläre Funktion definieren:

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

7voto

hotshot309 Punkte 1678

Zusammenfassung der vorangegangenen Kommentare:

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

wenn sie nicht einer Variablen zugewiesen ist, führt zu einem Syntaxfehler. Der Code wird als Funktionsanweisung (oder Definition) geparst, wodurch die schließenden Klammern syntaktisch falsch sind. Das Hinzufügen von Klammern um den Funktionsteil sagt dem Interpreter (und Programmierer), dass es sich um einen Funktionsausdruck (oder -aufruf) handelt, wie in

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

Dies ist eine selbstaufrufende Funktion, d. h. sie wird anonym erstellt und sofort ausgeführt, da der Aufruf in derselben Zeile erfolgt, in der sie deklariert wird. Diese selbstaufrufende Funktion wird mit der bekannten Syntax für den Aufruf einer Funktion ohne Argumente angegeben, wobei der Name der Funktion in Klammern gesetzt ist: (myFunction)(); .

Es gibt eine gute SO-Diskussion über die Syntax von JavaScript-Funktionen .

5voto

laycat Punkte 4741

Ich verstehe die Frage des Fragestellers so, dass:

Wie funktioniert dieser Zauber?

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

Ich kann mich irren. Aber die übliche Praxis, mit der die Menschen vertraut sind, ist:

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

Der Grund ist, dass JavaScript-Klammern AKA () Wenn der Parser auf das Schlüsselwort function stößt, weiß er, dass er es als Funktionsausdruck und nicht als Funktionsdeklaration parsen muss.

Quelle: Blogbeitrag Unmittelbar ausgelöster Funktionsausdruck (IIFE)

4voto

Nina Scholz Punkte 348155

Beispiele ohne Klammern:

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

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

ou

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

ou

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

arbeiten auch. die void bewirkt, dass der Ausdruck ausgewertet wird, sowie die Zuweisung und der Knall. letzteres funktioniert mit ~ , + , - , delete , typeof , einige der unären Operatoren ( void ist auch eine). nicht arbeiten sind natürlich ++ , -- wegen der Forderung nach einer Variablen.

ist der Zeilenumbruch nicht erforderlich.

3voto

Ionuț G. Stan Punkte 168218

Diese Antwort hat nicht unbedingt etwas mit der Frage zu tun, aber es könnte Sie interessieren, dass diese Art von Syntaxmerkmal nicht nur für Funktionen gilt. Wir können zum Beispiel immer etwas wie dieses tun:

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

Bezogen auf Funktionen. Da sie Objekte sind, 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 wissen Sie, wir müssen die Funktionen nicht einmal mit Klammern umgeben, um sie auszuführen. Jedenfalls solange wir versuchen, das Ergebnis einer Variablen zuzuweisen.

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

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

Eine andere Sache, die Sie mit Funktionen machen können, sobald Sie sie deklarieren, ist der Aufruf der new Operator über sie und erhalten ein Objekt. Die folgenden sind gleichwertig:

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

var obj = {
    foo : "bar"
};

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