200 votes

javascript fonction leading bang ! syntaxe

Je vois cette syntaxe dans quelques bibliothèques maintenant et je me demande quel en est l'intérêt. (note : je suis bien conscient des fermetures et de ce que fait le code, je ne m'intéresse qu'aux différences syntaxiques).

!function(){
  // do stuff
}();

En lieu et place de la plus courante

(function(){
  // do stuff
})();

pour les fonctions anonymes qui s'invoquent elles-mêmes.

Je me pose quelques questions. Tout d'abord, qu'est-ce qui permet à l'exemple du haut de fonctionner réellement ? Pourquoi le bang est-il nécessaire pour que cette déclaration soit syntaxiquement correcte ? On me dit également que + et je suis sûr qu'il y en a d'autres, à la place des !

Deuxièmement, quel est l'avantage ? Tout ce que je peux dire, c'est qu'il permet d'économiser un seul caractère, mais je ne peux pas imaginer qu'il s'agisse d'un avantage si important qu'il attire de nombreux adeptes. Y a-t-il un autre avantage qui m'échappe ?

La seule autre différence que je vois serait la valeur de retour de la fonction qui s'invoque elle-même, mais dans ces deux exemples, nous ne nous soucions pas vraiment de la valeur de retour de la fonction puisqu'elle n'est utilisée que pour créer une fermeture. Quelqu'un peut-il me dire pourquoi on pourrait utiliser la première syntaxe ?

96voto

c-smile Points 8609

Dans l'idéal, vous devriez être en mesure de faire tout cela simplement :

function(){
  // do stuff
}(); 

Cela signifie qu'il faut déclarer une fonction anonyme et l'exécuter. Mais cela ne fonctionnera pas en raison des spécificités de la grammaire JS.

La façon la plus simple d'y parvenir est donc d'utiliser une expression, par exemple UnaryExpression (et donc CallExpression) :

!function(){
  // do stuff
}(); 

Ou pour le plaisir :

-function(){
  // do stuff
}(); 

Ou bien :

+function(){
  // do stuff
}(); 

Ou même :

~function(){
  // do stuff
  return 0;
}( );

72voto

brainjam Points 11431

En Javascript, une ligne commençant par function est censée être une fonction déclaration et est censé ressembler à

function doSomething() {
}

Une fonction auto-invitante comme

function(){
  // do stuff
}();

ne correspond pas à cette forme (et provoquera une erreur de syntaxe à la première parenthèse ouvrante car il n'y a pas de nom de fonction), les crochets sont donc utilisés pour délimiter une fonction anonyme expression .

(function(){
  // do stuff
})();

Mais tout ce qui crée une expression (par opposition à une déclaration de fonction) fera l'affaire, d'où l'utilisation de la fonction ! . Il indique à l'interprète qu'il ne s'agit pas d'une déclaration de fonction. En dehors de cela, la préséance des opérateurs impose que la fonction soit invoquée avant la négation.

Je n'étais pas au courant de cette convention, mais si elle devient courante, elle peut contribuer à la lisibilité. Ce que je veux dire, c'est que toute personne lisant le !function au début d'un grand bloc de code s'attendra à une auto-invocation, de la même manière que nous sommes déjà conditionnés à nous attendre à la même chose lorsque nous voyons (function . Sauf que nous perdrons ces parenthèses gênantes. J'imagine que c'est la raison, plutôt qu'un gain de rapidité ou de nombre de caractères.

44voto

Smoe Points 631

En plus des choses qui ont déjà été dites, la syntaxe avec le ! est utile si vous écrivez du javascript sans point-virgule :

var i = 1
!function(){
  console.log('ham')
}()

i = 2
(function(){
  console.log('cheese')
})()

Le premier exemple produit "ham" comme prévu, mais le second génère une erreur parce que l'instruction i = 2 n'est pas terminée en raison de la parenthèse qui suit.

De même, dans les fichiers javascript concaténés, vous n'avez pas à vous soucier des points-virgules manquants dans le code précédent. Il n'est donc pas nécessaire d'utiliser l'habituel ;(function(){})() ; pour s'assurer que votre propre code ne sera pas cassé.

Je sais que ma réponse est un peu tardive mais je pense qu'elle n'a pas encore été mentionnée :)

6voto

Shaz Points 7458

D'une part, jsPerf montre que l'utilisation de ! (UnaryExpression's) sont généralement plus rapides. Parfois, elles sont égales, mais lorsqu'elles ne le sont pas, je n'ai pas vu l'expression non baisé un triomphe trop important sur les autres pour l'instant : http://jsperf.com/bang-function

Ceci a été testé sur la dernière Ubuntu avec le plus ancien (pour ainsi dire..) Chrome, version 8. Les résultats peuvent donc différer.

Edit : Que diriez-vous d'un truc un peu fou comme delete ?

delete function() {
   alert("Hi!"); 
}();

o void ?

void function() {
   alert("Hi!"); 
}();

3voto

Arman McHitaryan Points 847

Ainsi, avec negate " !" et tous les autres opérateurs unaires comme +,-,~, delete, void, beaucoup de choses ont été dites, juste pour résumer :

!function(){
  alert("Hi!");
}(); 

Ou

void function(){
  alert("Hi!");
}();

Ou

delete function(){
  alert("Hi!");
}();

Et quelques autres cas avec opérateurs binaires pour le plaisir :)

1 > function() {
   alert("Hi!"); 
}();

Ou

1 * function() {
   alert("Hi!"); 
}();

Ou

1 >>> function() {
   alert("Hi!"); 
}();

Ou encore

1 == function() {
   alert("Hi!"); 
}();

Laissez le ternaire à quelqu'un d'autre les gars :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X