funzione javascript che porta bang! syntax

Ho visto questa syntax su alcune librerie ora e mi chiedo quale sia il vantaggio. (nota che sono ben consapevole delle chiusure e di cosa sta facendo il codice, sono solo preoccupato delle differenze sintattiche)

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

In alternativa al più comune

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

per auto-invocare funzioni anonime.

Mi sto chiedendo alcune cose. Prima di tutto, che cosa consente effettivamente l’esempio più efficace? Perché è necessario il botto per rendere questa affermazione sintatticamente corretta? Mi è stato detto anche che + funziona, e sono sicuro che alcuni altri, al posto di !

In secondo luogo, qual è il vantaggio? Tutto quello che posso dire è che salva un singolo personaggio, ma non riesco a immaginare che sia un enorme vantaggio attrarre numerosi adottanti. C’è qualche altro beneficio che mi manca?

L’unica altra differenza che posso vedere sarebbe il valore di ritorno della funzione auto-invocante, ma in entrambi questi esempi, non ci interessa davvero il valore di ritorno della funzione poiché è usato solo per creare una chiusura. Quindi qualcuno può dirmi perché si potrebbe usare la prima syntax?

Idealmente dovresti essere in grado di fare tutto questo semplicemente come:

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

Ciò significa dichiarare la funzione anonima ed eseguirla. Ma questo non funzionerà a causa delle specifiche della grammatica JS.

La forma più breve per ottenere questo è usare un’espressione, ad esempio UnaryExpression (e così CallExpression):

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

O per il divertimento:

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

O:

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

O anche:

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

In Javascript, una riga che inizia con la function dovrebbe essere una dichiarazione di funzione e dovrebbe essere simile

 function doSomething() { } 

Una funzione autoinvitante come

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

non si adatta a questo modulo (e causerà un errore di syntax al primo paren di apertura perché non esiste un nome di funzione), quindi le parentesi sono utilizzate per delineare un’espressione di funzione anonima.

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

Ma qualsiasi cosa crei un’espressione (al contrario di una dichiarazione di funzione), quindi da qui il ! . Sta dicendo all’interprete che questa non è una dichiarazione di funzione. Oltre a ciò, la precedenza degli operatori indica che la funzione è invocata prima della negazione.

Non ero a conoscenza di questa convenzione, ma se diventa comune può contribuire alla leggibilità. Quello che voglio dire è che chiunque legge la !function cima a un grande blocco di codice si aspetta un autoinvocazione, il modo in cui siamo condizionati a aspettarci lo stesso quando vediamo (function . Tranne che perderemo quelle fastidiose parentesi Mi aspetto che questo sia il motivo, al contrario di qualsiasi risparmio in termini di velocità o numero di caratteri.

Oltre alle cose che sono già state dette, la syntax con il! è utile se scrivi javascript senza punto e virgola:

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

Il primo esempio restituisce ‘ham’ come previsto, ma il secondo genera un errore perché l’istruzione i = 2 non viene terminata a causa della parentesi seguente.

Inoltre, nei file javascript concatenati non ti devi preoccupare se il codice precedente manca di punto e virgola. Quindi non c’è bisogno del comune; (function () {}) (); per assicurarti che il tuo non si spezzi.

So che la mia risposta è in ritardo ma penso che non sia stata ancora menzionata 🙂

Per prima cosa, jsPerf mostra che l’utilizzo ! (UnaryExpression’s) sono di solito più veloci. A volte escono per essere uguali, ma quando non lo sono, non ho ancora visto trionfare il non-battuto sugli altri: http://jsperf.com/bang-function

Questo è stato testato sull’ultimo Ubuntu con il più vecchio (per esempio ..) Chrome, versione 8. Quindi i risultati potrebbero essere diversi, naturalmente.

Modifica: che ne dici di qualcosa di pazzo come delete ?

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

o void ?

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

Quindi, con il negato “!” e tutti gli altri operatori unari come +, -, ~, delete, void, molto è stato detto, solo per riassumere:

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

O

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

O

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

E qualche altro caso con gli operatori binari per divertimento 🙂

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

O

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

O

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

O anche

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

Lasciando il ternario per qualcun altro ragazzi 🙂

Come puoi vedere qui , il modo migliore per fare i metodi auto-invocati in javascript è utilizzare:

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