!function () {}();
!function () {}();
Antworten:
JavaScript-Syntax 101. Hier ist eine Funktionsdeklaration :
function foo() {}
Beachten Sie, dass es kein Semikolon ist: dies ist nur eine Funktion Erklärung . Sie benötigen einen Aufruf, foo()
um die Funktion tatsächlich auszuführen.
Wenn wir nun das scheinbar harmlose Ausrufezeichen hinzufügen: !function foo() {}
Es verwandelt es in einen Ausdruck . Es ist jetzt ein Funktionsausdruck .
Das !
allein ruft die Funktion natürlich nicht auf, aber wir können jetzt ()
am Ende setzen: Das !function foo() {}()
hat eine höhere Priorität als !
und ruft die Funktion sofort auf.
Der Autor speichert also ein Byte pro Funktionsausdruck. Eine besser lesbare Schreibweise wäre:
(function(){})();
Zuletzt !
wird der Ausdruck true zurückgegeben. Dies liegt daran, dass standardmäßig alle IIFE-Rückgaben undefined
, die uns mit !undefined
welchen zurücklassen true
. Nicht besonders nützlich.
!
gibt boolean zurück, das wissen wir alle, aber der große Punkt, den Sie ansprechen, ist, dass es auch die Funktionsdeklarationsanweisung in einen Funktionsausdruck konvertiert, sodass die Funktion sofort aufgerufen werden kann, ohne sie in Klammern zu setzen. Nicht offensichtlich und eindeutig die Absicht des Codierers.
var foo =
bricht die Mehrdeutigkeit von Aussage / Ausdruck und Sie können einfach schreiben var foo = function(bar){}("baz");
usw.
Die Funktion:
function () {}
gibt nichts zurück (oder undefiniert).
Manchmal möchten wir eine Funktion direkt beim Erstellen aufrufen. Sie könnten versucht sein, dies zu versuchen:
function () {}()
aber es ergibt sich ein SyntaxError
.
Wenn Sie den !
Operator vor der Funktion verwenden, wird er als Ausdruck behandelt, sodass wir ihn aufrufen können:
!function () {}()
Dies wird auch das boolean Gegenteil von dem Rückgabewert der Funktion zurückgegeben werden , in diesem Fall true
, da !undefined
ist true
. Wenn Sie möchten, dass der tatsächliche Rückgabewert das Ergebnis des Aufrufs ist, versuchen Sie es folgendermaßen:
(function () {})()
!
ist es, die Funktionsdeklaration in einen Funktionsausdruck umzuwandeln, das ist alles.
!function
Syntax
Es gibt einen guten Punkt für die Verwendung !
für den Funktionsaufruf, der im Airbnb-JavaScript-Handbuch markiert ist
Im Allgemeinen sollten Sie diese Technik für separate Dateien (auch als Module bezeichnet) verwenden, die später verkettet werden. Die Einschränkung hierbei ist, dass Dateien von Tools verkettet werden sollen, die die neue Datei in die neue Zeile setzen (was bei den meisten Concat-Tools ohnehin üblich ist). In diesem Fall !
hilft die Verwendung, Fehler zu vermeiden, wenn das zuvor verkettete Modul das nachfolgende Semikolon verpasst hat, und bietet dennoch die Flexibilität, sie ohne Bedenken in eine beliebige Reihenfolge zu bringen.
!function abc(){}();
!function bca(){}();
Funktioniert genauso wie
!function abc(){}();
(function bca(){})();
speichert aber ein Zeichen und willkürlich sieht besser aus.
Und übrigens jeder von +
, -
, ~
, void
haben Betreiber die gleiche Wirkung in Bezug auf die Funktion aufgerufen wird , sicher , wenn Sie etwas zu verwenden , haben von dieser Funktion zurück sie anders handeln würde.
abcval = !function abc(){return true;}() // abcval equals false
bcaval = +function bca(){return true;}() // bcaval equals 1
zyxval = -function zyx(){return true;}() // zyxval equals -1
xyzval = ~function xyz(){return true;}() // your guess?
Wenn Sie jedoch IIFE-Muster für eine Datei verwenden, um einen Modulcode zu trennen, und das Concat-Tool zur Optimierung verwenden (wodurch eine Zeile zu einem Dateijob wird), wird die Konstruktion ausgeführt
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
Führt eine sichere Codeausführung durch, genau wie bei einem ersten Codebeispiel.
Dieser wird einen Fehler auslösen, da JavaScript ASI seine Arbeit nicht ausführen kann.
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
Ein Hinweis zu unären Operatoren: Sie würden ähnliche Arbeiten ausführen, aber nur für den Fall, dass sie nicht im ersten Modul verwendet werden. Sie sind also nicht so sicher, wenn Sie nicht die vollständige Kontrolle über die Verkettungsreihenfolge haben.
Das funktioniert:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
Dies nicht:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
Es wird zurückgegeben, ob die Anweisung als falsch ausgewertet werden kann. z.B:
!false // true
!true // false
!isValid() // is not valid
Sie können es zweimal verwenden, um einen Wert in einen Booleschen Wert zu zwingen:
!!1 // true
!!0 // false
Um Ihre Frage direkter zu beantworten:
var myVar = !function(){ return false; }(); // myVar contains true
Bearbeiten: Dies hat den Nebeneffekt, dass die Funktionsdeklaration in einen Funktionsausdruck geändert wird. Der folgende Code ist beispielsweise ungültig, da er als Funktionsdeklaration interpretiert wird, bei der der erforderliche Bezeichner (oder Funktionsname ) fehlt :
function () { return false; }(); // syntax error
var myVar = !function(){ return false; }()
könnte weglassen der !
wie var myVar = function(){ return false; }()
und die Funktion wird ausgeführt , korrekt und der Rückgabewert wird unberührt.
true
mit !0
und false
mit !1
. Es werden 2 oder 3 Zeichen gespeichert.
Es ist nur, um ein Datenbyte zu speichern, wenn wir Javascript-Minimierung durchführen.
Betrachten Sie die unten stehende anonyme Funktion
function (){}
Um das Obige als selbstaufrufende Funktion zu verwenden, ändern wir im Allgemeinen den obigen Code als
(function (){}())
Jetzt haben wir zwei zusätzliche Zeichen hinzugefügt, (,)
abgesehen vom Hinzufügen ()
am Ende der Funktion, die zum Aufrufen der Funktion erforderlich sind. Bei der Minimierung konzentrieren wir uns im Allgemeinen darauf, die Dateigröße zu reduzieren. Wir können also auch die obige Funktion als schreiben
!function (){}()
Trotzdem sind beide selbstaufrufende Funktionen und wir speichern auch ein Byte. Anstelle von 2 Zeichen haben (,)
wir nur ein Zeichen verwendet!
! ist ein logischer NOT- Operator, es ist ein boolescher Operator, der etwas in das Gegenteil invertiert.
Obwohl Sie die Klammern der aufgerufenen Funktion umgehen können, indem Sie BANG (!) Vor der Funktion verwenden, wird die Rückgabe dennoch invertiert, was möglicherweise nicht Ihren Wünschen entspricht. Wie im Fall eines IEFE würde es undefiniert zurückgeben , was beim Invertieren zum booleschen Wert true wird.
Verwenden Sie stattdessen bei Bedarf die schließende Klammer und den BANG ( ! ).
// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what's happening.
(function(){ return false; }());
=> false
!(function(){ return false; }());
=> true
!!(function(){ return false; }());
=> false
!!!(function(){ return false; }());
=> true
Andere Operatoren, die arbeiten ...
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
Kombinierte Operatoren ...
+!(function(){ return false; }());
=> 1
-!(function(){ return false; }());
=> -1
!+(function(){ return false; }());
=> true
!-(function(){ return false; }());
=> true
~!(function(){ return false; }());
=> -2
~!!(function(){ return false; }());
=> -1
+~(function(){ return false; }());
+> -1
Durch das Ausrufezeichen gibt jede Funktion immer einen Booleschen Wert zurück.
Der Endwert ist die Negation des von der Funktion zurückgegebenen Werts.
!function bool() { return false; }() // true
!function bool() { return true; }() // false
Das Weglassen !
wäre eine in den obigen Beispielen Syntax .
function bool() { return true; }() // SyntaxError
Ein besserer Weg, dies zu erreichen, wäre jedoch:
(function bool() { return true; })() // true
!
Ändert die Art und Weise, wie die Laufzeit die Funktion analysiert. Dadurch behandelt die Laufzeit die Funktion als Funktionsausdruck (und nicht als Deklaration). Auf diese Weise kann der Entwickler die Funktion sofort mithilfe der ()
Syntax aufrufen . !
wendet sich auch selbst (dh Negation) auf das Ergebnis des Aufrufs des Funktionsausdrucks an.
Es ist eine andere Art, IIFE (sofort aufgerufener Funktionsausdruck) zu schreiben.
Seine andere Art zu schreiben -
(function( args ) {})()
gleich wie
!function ( args ) {}();
(function (args) {...})()
Syntax strikt bevorzugen und diese !function
Form den Minimierungs- und Verschleierungswerkzeugen überlassen .
!
negiert (entgegengesetzt) alles, was Sie als Ergebnis erwarten, dh wenn Sie haben
var boy = true;
undefined
boy
true
!boy
false
Wenn Sie anrufen boy
, wird Ihr Ergebnis sein true
, aber in dem Moment, in dem Sie das !
beim Anrufen hinzufügen boy
, !boy
wird Ihr Ergebnis sein false
. Mit anderen Worten, Sie meinen NotBoy , aber diesmal ist es im Grunde ein boolesches Ergebnis, entweder true
oder false
.
Das ist das gleiche, was mit dem !function () {}();
Ausdruck passiert. function () {}();
Wenn Sie nur ausführen, wird ein Fehler angezeigt. Wenn Sie jedoch !
direkt vor Ihrem function () {}();
Ausdruck hinzufügen , ist dies das Gegenteil von dem, function () {}();
was Sie zurückgeben sollte true
. Beispiel ist unten zu sehen:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true