Qu'est-ce que l'exclamation fait avant la fonction?

!function () {}(); 

Syntaxe JavaScript 101. Voici une déclaration de fonction :

 function foo() {} 

Notez qu'il n'y a pas de point-virgule: ce n'est qu'une déclaration de fonction. Vous auriez besoin d'une invocation, foo() , pour exécuter la fonction.

Maintenant, lorsque nous ajoutons le point d'exclamation apparemment inoffensif:! !function foo() {} il le transforme en expression . C'est maintenant une expression de fonction .

Le ! Seul n'appelle pas la fonction, bien sûr, mais nous pouvons maintenant mettre () à la fin !function foo() {}() qui a plus de priorité que ! Et appelle instantanément la fonction.

Donc, ce que l'auteur fait est de sauvegarder un octet par fonction; Une façon plus lisible d'écrire ceci serait ceci:

 (function(){})(); 

Enfin ! Rend l'expression vraie. C'est parce que, par défaut, tout retour IIFE undefined , qui nous laisse avec !undefined qui est true . Pas particulièrement utile.

La fonction:

 function () {} 

Ne retourne rien (ou indéfini).

Parfois, nous voulons appeler une fonction dès que nous la créons. Vous pourriez être tenté d'essayer ceci:

 function () {}() 

Mais il en résulte un SyntaxError .

En utilisant le ! Avant que la fonction ne l'entraîne comme une expression, nous pouvons l'appeler:

 !function () {}() 

Cela renverra également l'opposé booléen de la valeur de retour de la fonction, dans ce cas true , parce que !undefined est true . Si vous souhaitez que la valeur de retour réelle soit le résultat de l'appel, essayez de le faire de cette façon:

 (function () {})() 

Il est judicieux de l'utiliser ! Pour l'invocation de la fonction marquée sur le guide JavaScript airbnb

En général, une idée de l'utilisation de cette technique sur des fichiers distincts (autres que les modules) qui plus tard sont concaténés. La mise en garde ici est que les fichiers censés être concaténés par des outils qui mettent un nouveau fichier sur une nouvelle ligne (ce qui est en tout cas un comportement commun pour la plupart des outils concat). Dans ce cas, utilisez ! Aidera à éviter une erreur si le module virgule précédemment a manqué un point-virgule arrière, et pourtant cela donnera de la flexibilité pour les mettre dans un ordre sans se soucier.

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

Travailler comme

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

Mais enregistre deux caractères et des regards arbitraires mieux.

Et par la manière dont les opérateurs de + , - , ~ void ont le même effet, en termes de fonction d'appel, bien sûr, si vous utilisez quelque chose pour revenir de cette fonction, ils agiraient différemment.

 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? 

Mais si vous utilisez des modèles IIFE pour un fichier, une séparation de code de module et l'utilisation d'un outil de concaté pour l'optimisation (ce qui rend une ligne un travail de fichier), que la construction

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

Rendra l'exécution sûre du code, identique à un tout premier exemple de code.

Celui-ci lancera une erreur car JavaScript ASI ne pourra pas faire son travail.

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

Une note concernant les opérateurs unaires, ils feraient un travail similaire, mais seulement au cas où ils n'étaient pas dans le premier module. Ils ne sont donc pas si sûrs si vous n'avez pas le contrôle total de l'ordre de concaténation.

Cela marche:

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

Ce n'est pas:

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

Il renvoie si la déclaration peut être évaluée comme fausse. par exemple:

 !false // true !true // false !isValid() // is not valid 

Vous pouvez l'utiliser deux fois pour contraindre une valeur à booléen:

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

Donc, pour répondre plus directement à votre question:

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

Modifier: Il a l'effet secondaire de modifier la déclaration de fonction dans une expression de fonction. Par exemple, le code suivant n'est pas valide car il est interprété comme une déclaration de fonction qui manque l' identifiant requis (ou le nom de la fonction ):

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

Et voici quelque chose de plus que j'ai découvert de la console. Comme mentionné précédemment, le point d'exclamation rend la fonction retourner un boolean.

Pour le dernier de la syntaxe:

 ( function my_function() {} )() 

Nous pouvons faire quelque chose comme:

 (function add_them(a,b) { return a+b;} )(9,4) 

Comme une définition de fonction simultanée et un appel.

Modifier:
Maintenant, vous demandez à quoi sert '!' Définition de la fonction de type. Considérons ce qui suit:

 !function a_would_be_function() { alert("Do some junk but inside a function"); }() 

Vous souhaitez exécuter une fonction comme ci-dessus, mais sans '!' Générerait une erreur. J'espère que je suis clair.

C'est une autre façon d'écrire l'IIFE (expression de la fonction appelée immédiatement).

Son autre mode d'écriture –

 (function( args ) {})() 

pareil que

 !function ( args ) {}(); 

! Est un opérateur NOT logique, c'est un opérateur booléen qui inversera quelque chose à son contraire.

Bien que vous puissiez contourner les parenthèses de la fonction appelée en utilisant BANG (!) Avant la fonction, elle inversera le retour, ce qui pourrait ne pas être ce que vous vouliez. Comme dans le cas d'un IEFE, il renverra indéfini , qui, lorsqu'il est inversé, devient le booléen vrai.

Au lieu de cela, utilisez la parenthèse fermée et le BANG ( ! ) Si nécessaire.

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

Autres opérateurs qui fonctionnent …

 +(function(){ return false; }()); => 0 -(function(){ return false; }()); => -0 ~(function(){ return false; }()); => -1 

Opérateurs combinés …

 +!(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