wake-up-neo.com

Was macht das Ausrufezeichen vor der Funktion?

!function () {}();
1160
Sebastian Otto

JavaScript-Syntax 101. Hier ist eine Funktionsdeklaration:

function foo() {}

Beachten Sie, dass es kein Semikolon gibt: Dies ist nur eine Funktion Deklaration. Sie benötigen einen Aufruf, foo(), um die Funktion tatsächlich auszuführen.

Wenn wir nun das scheinbar harmlose Ausrufezeichen !function foo() {} hinzufügen, verwandelt es sich in ein Ausdruck. Es ist jetzt ein Funktionsausdruck.

Der ! allein ruft die Funktion natürlich nicht auf, aber wir können jetzt () am Ende setzen: !function foo() {}(), das eine höhere Priorität hat als ! und das sofort aufruft Funktion.

Der Autor speichert also ein Byte pro Funktionsausdruck. Eine lesbarere Schreibweise wäre:

(function(){})();

Schließlich bewirkt !, dass der Ausdruck true zurückgibt. Dies liegt daran, dass standardmäßig alle IIFE undefined zurückgeben, wodurch wir !undefined erhalten, was true ist. Nicht besonders nützlich.

1966
Neil

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 der Operator ! vor der Funktion verwendet wird, wird sie als Ausdruck behandelt, sodass wir sie folgendermaßen aufrufen können:

!function () {}()

Dadurch wird auch das Boolesche Gegenteil des Rückgabewerts der Funktion zurückgegeben, in diesem Fall true, da !undefinedtrue ist. Wenn der tatsächliche Rückgabewert das Ergebnis des Aufrufs sein soll, versuchen Sie es folgendermaßen:

(function () {})()
353
Michael Burr

Es gibt einen guten Grund, ! für den Funktionsaufruf zu verwenden, der mit Airbnb-JavaScript-Anleitung markiert ist

Im Allgemeinen wird empfohlen, diese Technik für separate Dateien (auch Module genannt) zu verwenden, die später verkettet werden. Die Einschränkung hierbei ist, dass Dateien mit 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 von !, Fehler zu vermeiden, wenn das zuvor verkettete Modul ein nachgestelltes Semikolon übersehen hat, und bietet dennoch die Flexibilität, diese ohne Bedenken in eine beliebige Reihenfolge zu bringen.

!function abc(){}();
!function bca(){}();

Funktioniert genauso wie

!function abc(){}();
(function bca(){})();

aber speichert ein zeichen und willkürlich sieht besser aus.

Übrigens hat jeder der Operatoren +, -, ~, void die gleiche Auswirkung, wenn Sie die Funktion aufrufen müssen von dieser Funktion zurückzukehren, würden sie anders handeln.

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 und eine Modulcodetrennung verwenden und das Concat-Tool für die Optimierung verwenden (was eine Zeile und eine Datei zum Job macht), müssen Sie konstruieren

!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()

Ausführen von sicherem Code, genau wie bei einem ersten Codebeispiel.

Dieser löst einen Fehler aus, da JavaScript ASI seine Arbeit nicht ausführen kann.

!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()

Eine Anmerkung 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*/}()
55
dmi3y

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 konvertieren:

!!1    // true
!!0    // false

Um Ihre Frage direkter zu beantworten:

var myVar = !function(){ return false; }();  // myVar contains true

Edit: Dies hat den Nebeneffekt, dass die Funktionsdeklaration in einen Funktionsausdruck geändert wird. Z.B. Der folgende Code ist ungültig, da er als Funktionsdeklaration interpretiert wird, bei der die erforderliche Kennung (oder Funktion fehlt Name ):

function () { return false; }();  // syntax error
28
gilly3

Ein Ausrufezeichen bewirkt, dass jede Funktion immer einen Booleschen Wert zurückgibt. Der Endwert ist die Negation des von der Funktion zurückgegebenen Werts.

!function bool() { return false; }() // true
!function bool() { return true; }() // false

Das Weglassen von ! in den obigen Beispielen wäre ein SyntaxError.

function bool() { return true; }() // SyntaxError

Ein besserer Weg, dies zu erreichen, wäre jedoch:

(function bool() { return true; })() // true
6
oozzal

! ist ein logischer NICHT Operator, ein boolescher Operator, der etwas in das Gegenteil umkehrt.

Obwohl Sie die Klammern der aufgerufenen Funktion umgehen können, indem Sie vor der Funktion BANG (!) Eingeben, wird die Rückgabe trotzdem invertiert, was möglicherweise nicht Ihren Wünschen entspricht. Wie im Fall eines IEFE würde es undefiniertes zurückgeben, das, wenn es invertiert wird, zum booleschen Wert true wird.

Verwenden Sie stattdessen die schließende Klammer und den BANG (!), falls erforderlich.

// 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 funktionieren ...

+(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
5
SoEzPz

Es ist nur ein Byte von Daten zu speichern, wenn wir Javascript-Minimierung tun.

betrachten Sie die folgende anonyme Funktion

function (){}

Um den obigen Code als selbstaufrufende Funktion zu definieren, ändern wir den obigen Code im Allgemeinen als

(function (){}())

Jetzt haben wir zwei zusätzliche Zeichen (,) hinzugefügt, abgesehen vom Hinzufügen von () am Ende der Funktion, die zum Aufrufen der Funktion erforderlich ist. Bei der Minimierung konzentrieren wir uns im Allgemeinen darauf, die Dateigröße zu reduzieren. So können wir die obige Funktion auch als schreiben

!function (){}()

Trotzdem sind beide Funktionen selbstaufrufend und wir speichern auch ein Byte. Anstelle von 2 Zeichen (,) haben wir nur ein Zeichen ! verwendet

5
Varatharaj

Es ist eine andere Art, IIFE zu schreiben (Ausdruck einer sofort aufgerufenen Funktion).

Seine andere Art zu schreiben -

(function( args ) {})()

gleich wie

!function ( args ) {}();
2
kamal

Sparen wir noch ein paar Bytes!

(() => {})()

beispiel:

(() => {return "yeah"})()
0
Zibri

! negiert (entgegengesetzt) ​​das, was Sie als Ergebnis erwarten, d. H. Wenn Sie haben

var boy = true;
undefined
boy
true
!boy
false

wenn Sie boy aufrufen, ist Ihr Ergebnis true, aber in dem Moment, in dem Sie ! hinzufügen, wenn Sie boy aufrufen, dh !boy, ist Ihr Ergebnis false. Das heißt mit anderen Worten NotBoy, aber diesmal ist es im Grunde ein boolesches Ergebnis, entweder true oder false.

Das gleiche passiert mit dem Ausdruck !function () {}();, wenn nur function () {}(); ausgeführt wird, wird ein Fehler gemeldet, aber das Hinzufügen von ! direkt vor Ihrem Ausdruck function () {}(); macht ihn zum Gegenteil der function () {}();, die Sie zurückgeben soll true. Beispiel kann unten gesehen werden:

function () {}();
SyntaxError: function statement requires a name
!function () {}();
true
0
antzshrek