function de javascript levando estrondo! syntax

Eu tenho visto essa syntax em algumas bibliotecas agora e estou me perguntando qual é o benefício. (note que estou bem ciente dos encerramentos e do que o código está fazendo, estou preocupado apenas com as diferenças sintáticas)

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

Como alternativa ao mais comum

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

para auto invocar funções anônimas.

Estou me perguntando algumas coisas. Em primeiro lugar, o que está permitindo que o exemplo principal funcione de verdade? Por que o estrondo é necessário para tornar esta afirmação sintaticamente correta? Também me disseram que + funciona, e tenho certeza que outros, no lugar de !

Em segundo lugar, qual é o benefício? Tudo o que posso dizer é que ele salva um único caractere, mas não posso imaginar que isso seja um benefício tão grande para atrair inúmeros usuários. Existe algum outro benefício que eu estou perdendo?

A única outra diferença que posso ver seria o valor de retorno da function de auto-chamada, mas em ambos os exemplos, não nos importamos realmente com o valor de retorno da function, uma vez que ela é usada apenas para criar um fechamento. Então alguém pode me dizer por que alguém pode usar a primeira syntax?

Idealmente, você deve ser capaz de fazer tudo isso simplesmente como:

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

Isso significa declarar function anônima e executá-la. Mas isso não funcionará devido a especificidades da gramática JS.

Portanto, a forma mais curta de conseguir isso é usar alguma expressão, por exemplo, UnaryExpression (e, portanto, CallExpression):

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

Ou para a diversão:

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

Ou:

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

Ou até mesmo:

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

Em Javascript, espera-se que uma linha que começa com a function seja uma declaração de function e que se pareça com

 function doSomething() { } 

Uma function de auto-invocação como

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

não se encheckbox nesse formulário (e causará um erro de syntax no primeiro parêntese de abertura porque não há nome de function), portanto, os colchetes são usados ​​para delinear uma expressão de function anônima.

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

Mas qualquer coisa que crie uma expressão (em oposição a uma declaração de function) fará, portanto, o ! . Está dizendo ao intérprete que isso não é uma declaração de function. Além disso, a precedência do operador determina que a function seja invocada antes da negação.

Eu não estava ciente dessa convenção, mas se ela se tornar comum, isso pode contribuir para a legibilidade. O que quero dizer é que qualquer um que ler a !function No topo de um grande bloco de código esperará uma auto-invocação, a maneira como estamos condicionados a esperar o mesmo quando vemos (function . Exceto que perderemos esses parênteses irritantes Eu esperaria que essa é a razão, ao contrário de qualquer economia de velocidade ou contagem de caracteres.

Além das coisas que já foram ditas, a syntax com o! é útil se você escrever javascript sem ponto e vírgula:

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

O primeiro exemplo gera “ham” como esperado, mas o segundo lançará um erro porque a instrução i = 2 não é terminada devido aos seguintes parênteses.

Também em arquivos javascript concatenados, você não precisa se preocupar se o código anterior não tiver ponto e vírgula. Portanto, não há necessidade do comum (function () {}) (); para ter certeza de que o seu próprio não irá quebrar.

Eu sei que a minha resposta é meio tarde, mas eu acho que ainda não foi mencionado 🙂

Por um lado, jsPerf mostra que usando ! (UnaryExpression’s) são geralmente mais rápidos. Às vezes, eles saem para ser iguais, mas quando não são, eu ainda não vi o não-batido triunfar muito sobre os outros: http://jsperf.com/bang-function

Isso foi testado no Ubuntu mais recente com o mais antigo (por exemplo …) Chrome, versão 8. Assim, os resultados podem ser diferentes, é claro.

Edit: Como sobre algo louco como delete ?

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

ou void ?

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

Então, com negar “!” e todos os outros operadores unários como +, -, ~, delete, void, muito foi dito, apenas para resumir:

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

Ou

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

Ou

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

E mais alguns casos com operadores binários para diversão 🙂

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

Ou

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

Ou

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

Ou mesmo

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

Deixando o ternário para outra pessoa pessoal 🙂

Como você pode ver aqui , a melhor maneira de fazer os methods auto-invocados em javascript é usando:

 (function(){}()); -> 76,827,475 ops/sec !function(){}(); -> 69,699,155 ops/sec (function(){})(); -> 69,564,370 ops/sec