Was ist das
In JavaScript erstellt jede Funktion, wenn sie aufgerufen wird, einen neuen Ausführungskontext. Da Variablen und Funktionen, die in Funktionen definiert sind, die einzigen Variablen sind, auf die intern und nicht extern aufgerufen werden, bietet der von der Funktion bereitgestellte Kontext eine sehr einfache Möglichkeit, private Variablen zu erstellen.
Funktion makeCounter () {var i = 0; return function () {console.log (++ i); }; } // Denken Sie daran: `counter" und `counter2` haben ihre eigenen Variablen` i'var counter = makeCounter (); counter (); // 1Counter (); // 2var counter 2 = makeCounter (); counter 2 (); // 1Counter2 (); ////////// // /////////// // // // // // // // // // // // Itre -Referenror: Ich bin nicht definiert (ich wird in makounter) (IR -IT IS IS IS IS IS IS IST IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IS IN.In vielen Fällen benötigen Sie möglicherweise keine Funktion wie das, was auch immer mehrere akkumulierte Werte zurückgibt, und Sie können sie nur einmal aufrufen, um einen einzelnen Wert zu erhalten. In einigen anderen Fällen müssen Sie den Rückgabewert nicht einmal explizit kennen.
Sein Kern
Egal, egal ob Sie eine Funktion wie Funktion foo () {} oder var foo = function () {} definieren, wenn Sie aufrufen, müssen Sie danach ein Paar Klammern hinzufügen, wie Foo ().
// Die unten definierte Funktion kann aufgerufen werden, indem nach dem Funktionsnamen ein Klammern nach dem Funktionsnamen `foo ()`, // ist, da Foo nur eine Referenzvariable var foo = function () {/ * code */} `Relativ zum Funktionxpression` function () {/ * code */}} var foo = Funktion () {{/ * code */}/}/}/}/}/}/}/}/}/}/}/}/{} //. Klammern danach? function () { / * code * /} (); // syntaxError: unerwartetes Token (Wie Sie sehen können, wird hier ein Fehler gefangen. Wenn Klammern hinter einer Funktion erscheinen, um eine Funktion aufzurufen, unabhängig davon, ob Sie auf ein solches Funktionsschlüsselwort in der globalen Umgebung oder in der lokalen Umgebung stoßen, behandelt es dies standardmäßig als Funktionserklärung und nicht als Funktionsausdruck. Wenn Sie den Klammern nicht ausdrücklich mitteilen, dass es sich um einen Ausdruck handelt, behandelt es ihn ohne Namen als Funktion und wirft einen Fehler auf, da die Funktionserklärung einen Namen erfordert.
Frage 1: Kann ich hier eine Frage vorstellen? Können wir auch die Funktion var foo = function () {console.log (1)} () direkt wie diese aufrufen, und die Antwort ist in Ordnung.
Frage 2: Ebenso können wir auch über eine Frage nachdenken. Wenn eine solche Funktionserklärung direkt mit Klammern danach aufgerufen wird, was passiert dann? Bitte beachten Sie die Antwort unten.
Funktion, Klammern, Fehler
Interessanterweise wird der gleiche Fehler geworfen, wenn Sie einen Namen für eine Funktion angeben und ein Klammern hinter sich legen, diesmal jedoch aus einem anderen Grund. Wenn Klammern nach einem Funktionsausdruck platziert werden, zeigt dies an, dass dies eine genannte Funktion ist und Klammern nach einer Deklaration platziert werden. Dies bedeutet, dass sie vollständig von der vorherigen Funktionserklärung getrennt sind. Zu diesem Zeitpunkt sind Klammern nur eine einfache Darstellung eines Klammerns (Klammern, die zur Kontrolle der Betriebsvorrangspriorität verwendet werden).
// Die Funktionserklärung ist jedoch syntaktisch ungültig, es ist immer noch eine Deklaration und die folgenden Klammern sind ungültig, da die Klammern die Expressionsfunktion foo () {/* code*/} (); // syntaxError einbeziehen müssen: Unerwartetes Token // Jetzt setzen Sie einen Ausdruck in die Parenterhes, ohne dass die Funktion ein Fehler erledigt. */} (1) // Es entspricht der folgenden, eine Funktionserklärung folgt einem Ausdruck, der überhaupt keine Beziehung hat: Funktion foo () {/ *Code */} (1);Funktionsausdrücke sofort ausführen (iife)
Glücklicherweise ist es einfach, Grammatikfehler zu beheben. Die beliebteste und anerkannte Methode besteht darin, Funktionserklärungen in Klammern zu wickeln, um dem Parser einen Funktionsausdruck auszudrücken, da in JavaScript Klammern keine Deklarationen enthalten können. Wenn die Klammern auf das Schlüsselwort der Funktion stoßen, um die Funktion zu wickeln, kann es als Funktionsausdruck anstelle einer Funktionserklärung analysiert werden. Achten Sie darauf, zu verstehen, dass sich die Klammern hier von den obigen Klammern unterscheiden, wenn sie auf Funktionen stoßen, das heißt,
Wenn Klammern am Ende einer anonymen Funktion erscheinen und eine Funktion aufrufen möchten, werden die Funktion standardmäßig als Funktionserklärung behandelt.
Wenn Sie eine Funktion in Klammern einwickeln, analysiert sie die Funktion standardmäßig als Ausdruck, anstatt die Funktion zu deklarieren.
// Both patterns can be used to call a function expression immediately, using the execution of the function to create private variables (function(){/* code */}());//Crockford recommends this one, the expression in brackets represents the function immediately (function(){/* code */})();//But this one works just as well, the expression in brackets represents the function expression // Because the point of the parens or coercing Operatoren müssen // zwischen Funktionsausdrücken und Funktionserklärungen disamsamsamsamsieren. Sie können // weggelassen werden, wenn der Parser bereits einen Ausdruck erwartet (aber bitte sehen Sie die // "Wichtige Anmerkung" unten) .var i = function () {return 10;} (); true && function () {/*code*/} (). Möglicherweise können Sie Bytes speichern, indem Sie einen unären Operator vor Ihre Funktion nehmen! function () {/ * code */} (); ~ function () {/ * code */} (); - function () {/ * code */} ();+function () {/ * code */} (); // Hier ist eine andere Variation von @kuvos - Ich bin mir der Aufführung nicht sicher // Wirkungsmittel, falls eins, wenn überhaupt, von `Newword, aber es ist das Keyword, aber es ist das Keyword, aber es ist das Keyword, aber es ist das Keyword, aber es ist das Keyword, aber es ist das Keyword, aber es ist das Keyword, aber es ist das Keyword, aber es ist das Keyword, aber es ist das`. http://twitter.com/kuvos/status/18209252090847232New Function () {/ * Code */} Neue Funktion () {/ * Code */} () // benötigen nur Parens, wenn Argumente übergeben werden müssen, wenn Argumente übergeben werden müssenWichtige Anmerkungen zu Klammern
In einigen Fällen ist es nicht erforderlich, den Funktionsausdruck zu umgeben, wenn zusätzliche mehrdeutige Klammern um den Funktionsausdruck herum sind (da die Klammern bereits als Ausdruck ausgedrückt werden), aber dies ist immer noch eine gute Idee, wenn die Klammern den Funktionsausdruck bezeichnen.
Solche Klammern geben an, dass der Funktionsausdruck sofort aufgerufen wird und dass die Variable das Ergebnis der Funktion und nicht die Funktion selbst speichert. Wenn dies ein sehr langer Funktionsausdruck ist, speichert dies Zeit als Personen, die Ihren Code lesen, ohne zum Ende der Seite scrollen zu müssen, um festzustellen, ob die Funktion aufgerufen wird.
Wenn Sie einen klaren und klaren Code schreiben, ist es in der Regel erforderlich, dass JavaScript Fehlern wirft, und es ist auch erforderlich, andere Entwickler daran zu hindern, Fehler zu werfen, die Sie wtferror werfen!
Speichern Sie den Status der Schließung
Genau wie wenn eine Funktion unter ihrem Namen aufgerufen wird, werden die Parameter übergeben, und wenn der Funktionsausdruck sofort aufgerufen wird, werden die Parameter übergeben. Ein unmittelbar bezeichneter Funktionsausdruck kann verwendet werden, um Werte zu sperren und den Zustand zu diesem Zeitpunkt effektiv zu speichern, da jede in einer Funktion definierte Funktion Parameter und Variablen verwenden kann, die von der externen Funktion eingegeben werden (diese Beziehung wird als Verschluss bezeichnet).
// Es kann nicht funktionieren, wie Sie denken, denn der Wert von "Ich bin nie gesperrt. // Umgekehrt wird die Gesamtzahl aller Elemente angeklickt, wenn jeder Link geklickt wird (die Schleife wurde gut ausgeführt), da dies der wahre Wert von "Ich" zu diesem Zeitpunkt ist. var elems = document.GetElementsByTagName ('a'); für (var i = 0; i <elems.length; i ++) {Elems [i] .AddeventListener ('click', function (e) {e.preventDefault (); alert ('i am link #'+ i)},}, ~}, ~, `| Der Wert ist in `lockedInindex` gesperrt. // Wenn die Schleife ausgeführt wird, obwohl der numerische Wert des "I" -Werte die Summe aller Elemente ist, wird jedes Mal, wenn der Funktionsausdruck aufgerufen wird, der "Sperrindex" -Werwert in IIfe der von "I" übergebene Wert. Wenn der Link geklickt wird, wird der korrekte Wert angezeigt. var elems = document.GetElementsByTagName ('a'); für (var i = 0; i <elems.length; i ++) {(function (lockedInindex) {Elems [i] .AdDeVentListener ('Click', Funktion (e) {E.PreventDefault (); Alert ('i Am Link #'++ #'+ #'+; }) (i);} // Sie können IIFE auch wie folgt verwenden, nur mit Klammern die Klick -Verarbeitungsfunktion und nicht die gesamte adventListener "einbeziehen. //No matter which way, both examples can be locked with IIFE, but I found that the previous example is more readable var elems = document.getElementsByTagName( 'a' );for ( var i = 0; i < elems.length; i++ ) { elems[ i ].addEventListener( 'click', (function( lockedInIndex ){ return function(e){ e.preventDefault(); alert ('Ich bin Link #' + lockedInIndex); }Denken Sie daran, dass LockedInIndex in diesen letzten beiden Beispielen ohne Probleme auf I zugreifen kann, aber die Verwendung eines anderen benannten Bezeichners als Parameter der Funktion kann das Konzept erleichtert, um zu interpretieren.
Einer der wichtigsten Vorteile bei der Durchführung einer Funktion besteht
Was ist das Problem bei der selbstverständlichen anonymen Funktion ("selbst ausführende anonyme Funktion")?
Sie haben gesehen, dass es mehrmals erwähnt wird, aber es wird noch nicht so klar erklärt. Ich würde vorschlagen, den Begriff in "sofort angerufene Funktionsausdruck" oder iife zu ändern, wenn Sie die Abkürzung mögen.
Was ist eine sofort in Frage behaupte Funktionsausdruck? Es lässt einen Funktionsausdruck sofort aufgerufen. Es ist wie ein Funktionsausdruck, der Sie zum Anrufen führt.
Ich denke, Mitglieder der JavaScript-Community sollten in der Lage sein, Begriffe, unmittelbare Funktionen des Funktionsausdrucks und IIF in ihren Artikeln oder Aussagen zu akzeptieren, da ich der Meinung bin, dass es einfacher ist, das Konzept zu verstehen, und der Begriff "selbst extrazielle anonyme Funktion" ist wirklich nicht genau genug.
// Folgendes ist eine selbstversorgende Funktion, die rekursiv seine eigene Funktion foo () {foo ();}; // Dies ist eine selbstversorgende anonyme Funktion. Da es keine Kennung hat, muss es die Eigenschaft "Argumente.Callee" verwenden, um sie selbst zu nennen var foo = function () {argumente.callee ();}; // Dies kann als selbstverwöhnliche anonyme Funktion angesehen werden, aber es ist auch machbar, wenn Sie es durch "foo" -Foo-Funktion nennen. Anonyme Funktion 'wie diese, auch wenn sie sich nicht selbst ausgeführt hat, weil sie sich nicht selbst nennt. Dann wurde es einfach sofort gerufen. (function () {/*code*/} ()); // Hinzufügen einer Kennung zu einem Funktionsausdruck (dh Erstellen einer benannten Funktion) wird unserem Debuggen von großer Hilfe sein. Einmal benannt, wird die Funktion nicht mehr anonym sein. (Funktion foo () {/ * code */} ()); // iifes kann auch selbst ausgeführt werden, obwohl es vielleicht nicht das nützlichste Muster ist (Funktion () {Argumente Fantastisch, huh? (Funktion foo () {foo ();} ());Hoffentlich wird das obige Beispiel Ihnen ein klareres Verständnis des Begriffs selbst executieren, der etwas irreführend ist, da es keine eigene Funktion ausführt, obwohl die Funktion ausgeführt wurde. In ähnlicher Weise müssen nicht auf anonyme Funktionen hinweisen, da sofort aufgerufene Funktionsausdruck entweder eine benannte Funktion oder eine anonyme Funktion sein kann.
Zuletzt: Modulmodus
Wenn ich einen Funktionsausdruck nenne und mich mindestens einmal an das Modulmuster erinnere, werde ich es höchstwahrscheinlich ignorieren. Wenn Sie nicht über das Modulmuster in JavaScript verfügen, ist es meinem folgenden Beispiel sehr ähnlich, aber der Rückgabewert verwendet ein Objekt anstelle der Funktion.
var counter = (function () {var i = 0; return {get: function () {return i;}, set: function (val) {i = val;}, Increment: function () {return ++ i;}}} ()); counter.get (); // 0 counter.set (3); counter.increment (); // 4 counterDie Modulmodusmethode ist nicht nur sehr leistungsfähig, sondern auch einfach. Mit sehr wenig Code können Sie die Benennung in Bezug auf Methoden und Attribute effektiv verwenden. In einem Objekt minimiert das Organisieren aller Modulcodes die Verschmutzung globaler Variablen und erzeugt die Verwendung von Variablen.