J'ai vu cette syntaxe sur quelques bibliothèques maintenant et je me demande quel est l'avantage. (notez que je suis bien au courant des fermetures et de ce que fait le code, je ne m'inquiète que des différences syntaxiques)
!function(){
// do stuff
}();
Comme alternative aux plus courants
(function(){
// do stuff
})();
pour l'auto-invocation de fonctions anonymes.
Je me pose quelques questions. Tout d'abord, qu'est-ce qui permet au meilleur exemple de fonctionner? Pourquoi le coup est-il nécessaire pour rendre cette déclaration syntaxiquement correcte? On me dit aussi que +
fonctionne, et je suis sûr que certains autres, à la place de !
Deuxièmement, quel est l'avantage? Tout ce que je peux dire, c'est qu'il enregistre un seul personnage, mais je ne peux pas imaginer que c'est un énorme avantage pour attirer de nombreux adoptants. Y a-t-il un autre avantage qui me manque?
La seule autre différence que je peux voir serait la valeur de retour de la fonction auto-invoquante, mais dans ces deux exemples, nous ne nous soucions pas vraiment de la valeur de retour de la fonction car elle n'est utilisée que pour créer une fermeture. Alors, quelqu'un peut-il me dire pourquoi on pourrait utiliser la première syntaxe?
Idéalement, vous devriez pouvoir faire tout cela simplement:
function(){
// do stuff
}();
Cela signifie 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 forme la plus courte pour y parvenir est d'utiliser une expression, par exemple UnaryExpression (et donc CallExpression):
!function(){
// do stuff
}();
Ou pour le plaisir:
-function(){
// do stuff
}();
Ou:
+function(){
// do stuff
}();
Ou même:
~function(){
// do stuff
return 0;
}( );
En Javascript, une ligne commençant par function
devrait être une fonction instruction et devrait ressembler à
function doSomething() {
}
Une fonction auto-invoquante comme
function(){
// do stuff
}();
ne correspond pas à cette forme (et provoquera une erreur de syntaxe au premier paren d'ouverture car il n'y a pas de nom de fonction), donc les crochets sont utilisés pour délimiter une fonction anonyme expression.
(function(){
// do stuff
})();
Mais tout ce qui crée une expression (par opposition à une instruction de fonction) fera l'affaire, d'où la !
. C'est dire à l'interprète que ce n'est pas une déclaration de fonction. En dehors de cela, la priorité de l'opérateur 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 quiconque lit le !function
au sommet d'un grand bloc de code attendra une auto-invocation, la façon dont nous sommes déjà conditionnés à attendre la même chose quand nous voyons (function
. Sauf que nous perdrons ces parenthèses ennuyeuses. Je m'attends à ce que ce soit la raison, par opposition à toute économie de vitesse ou de nombre de caractères.
Outre les choses qui ont déjà été dites, la syntaxe avec le! est utile si vous écrivez javascript sans point-virgule:
var i = 1
!function(){
console.log('ham')
}()
i = 2
(function(){
console.log('cheese')
})()
Le premier exemple génère "ham" comme prévu, mais le second générera une erreur car l'instruction i = 2 n'est pas terminée en raison de la parenthèse suivante.
De plus, dans les fichiers javascript concaténés, vous n'avez pas à vous inquiéter si le code précédent manque de points-virgules. Donc pas besoin du commun; (function () {}) (); pour vous assurer que le vôtre ne se cassera pas.
Je sais que ma réponse est un peu tard mais je pense qu'elle n'a pas encore été mentionnée :)
D'une part, jsPerf montre que l'utilisation de !
(UnaryExpression) sont généralement plus rapides. Parfois, ils se révèlent égaux, mais quand ils ne le sont pas, je n'ai pas encore vu le non frappé triompher trop des autres : http://jsperf.com/bang-function
Cela a été testé sur le dernier Ubuntu avec le plus ancien (disons ..) Chrome, version 8. Les résultats peuvent donc bien sûr différer.
Edit: Que diriez-vous de quelque chose de fou comme delete
?
delete function() {
alert("Hi!");
}();
ou void
?
void function() {
alert("Hi!");
}();
Donc, avec niez "!" et tous les autres opérateurs unaires comme +, -, ~, delete, void, beaucoup a été dit, 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 même
1 == function() {
alert("Hi!");
}();
Quitter le ternaire pour quelqu'un d'autre :)
Comme vous pouvez le voir ici , la meilleure façon de faire des méthodes auto-invoquées en javascript est d'utiliser:
(function(){}()); -> 76,827,475 ops/sec
!function(){}(); -> 69,699,155 ops/sec
(function(){})(); -> 69,564,370 ops/sec