!function () {}();
!function () {}();
Risposte:
Sintassi JavaScript 101. Ecco una dichiarazione di funzione :
function foo() {}
Nota che non c'è punto e virgola: questa è solo una dichiarazione di funzione . Avresti bisogno di una chiamata foo()
, per eseguire effettivamente la funzione.
Ora, quando aggiungiamo il punto esclamativo apparentemente innocuo: !function foo() {}
lo trasforma in un'espressione . Ora è un'espressione di funzione .
Il !
solo non invoca la funzione, ovviamente, ma ora possiamo mettere ()
alla fine: !function foo() {}()
che ha una precedenza più alta di !
e chiama immediatamente la funzione.
Quindi ciò che l'autore sta facendo è salvare un byte per espressione di funzione; un modo più leggibile di scrivere sarebbe questo:
(function(){})();
Infine, !
restituisce l'espressione vera. Questo perché di default tutto il ritorno IIFE undefined
, che ci lascia con ciò !undefined
che è true
. Non particolarmente utile.
!
restituisce il valore booleano, lo sappiamo tutti, ma il punto importante che fai è che converte anche l'istruzione dichiarazione di funzione in un'espressione di funzione in modo che la funzione possa essere immediatamente invocata senza racchiuderla tra parentesi. Non ovvio, e chiaramente l'intento del programmatore.
var foo =
rompe l'ambiguità dell'affermazione / espressione e puoi semplicemente scrivere var foo = function(bar){}("baz");
ecc.
La funzione:
function () {}
non restituisce nulla (o non definito).
A volte vogliamo chiamare una funzione nel momento in cui la creiamo. Potresti essere tentato di provare questo:
function () {}()
ma risulta in a SyntaxError
.
L'uso !
dell'operatore prima della funzione fa sì che venga trattata come un'espressione, quindi possiamo chiamarla:
!function () {}()
Ciò restituirà anche l'opposto booleano del valore restituito della funzione, in questo caso true
, perché !undefined
è true
. Se desideri che il valore restituito effettivo sia il risultato della chiamata, prova a farlo in questo modo:
(function () {})()
!
è trasformare la dichiarazione di funzione in un'espressione di funzione, tutto qui.
!function
sintassi
C'è un buon punto per usare !
per l'invocazione della funzione segnata sulla guida JavaScript di airbnb
Generalmente idea di utilizzare questa tecnica su file separati (aka moduli) che successivamente vengono concatenati. L'avvertenza qui è che i file dovrebbero essere concatenati da strumenti che mettono il nuovo file sulla nuova riga (che è comunque un comportamento comune per la maggior parte degli strumenti concat). In tal caso, l'utilizzo !
consentirà di evitare errori nel caso in cui un modulo precedentemente concatenato abbia perso il punto e virgola, e tuttavia ciò darà la flessibilità di metterli in qualsiasi ordine senza preoccupazioni.
!function abc(){}();
!function bca(){}();
Funzionerà come
!function abc(){}();
(function bca(){})();
ma salva un personaggio e l'aspetto arbitrario è migliore.
E tra l'altro qualsiasi +
, -
, ~
, void
gli operatori hanno lo stesso effetto, in termini di invocare la funzione, di sicuro se si deve usare qualcosa di tornare da quella funzione si comporterebbero in modo diverso.
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?
ma se si utilizzano i modelli IIFE per la separazione del codice di un file in un modulo e si utilizza lo strumento concat per l'ottimizzazione (che rende una riga un lavoro per file), quindi costruzione
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
Farà l'esecuzione del codice in modo sicuro, come nel primo esempio di codice.
Questo genererà un errore perché JavaScript ASI non sarà in grado di fare il suo lavoro.
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
Una nota per quanto riguarda gli operatori unari, avrebbero fatto un lavoro simile, ma solo nel caso in cui non fossero stati usati nel primo modulo. Quindi non sono così sicuri se non si ha il controllo totale sull'ordine di concatenazione.
Questo funziona:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
Questo non:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
Restituisce se l'istruzione può essere valutata come falsa. per esempio:
!false // true
!true // false
!isValid() // is not valid
Puoi usarlo due volte per forzare un valore in booleano:
!!1 // true
!!0 // false
Quindi, per rispondere più direttamente alla tua domanda:
var myVar = !function(){ return false; }(); // myVar contains true
Modifica: ha l'effetto collaterale di cambiare la dichiarazione di funzione in un'espressione di funzione. Ad esempio il seguente codice non è valido perché viene interpretato come una dichiarazione di funzione in cui manca l' identificatore richiesto (o il nome della funzione ):
function () { return false; }(); // syntax error
var myVar = !function(){ return false; }()
potrebbe omettere il !
simile var myVar = function(){ return false; }()
e la funzione verrà eseguita correttamente e il valore restituito rimarrà intatto.
true
con !0
e false
con !1
. Salva 2 o 3 caratteri.
È solo per salvare un byte di dati quando eseguiamo la minificazione javascript.
considera la seguente funzione anonima
function (){}
Per rendere quanto sopra come funzione auto-invocante, cambieremo generalmente il codice sopra come
(function (){}())
Ora abbiamo aggiunto due caratteri aggiuntivi (,)
oltre a aggiungere ()
alla fine della funzione che è necessario per chiamare la funzione. Nel processo di minificazione ci concentriamo generalmente per ridurre le dimensioni del file. Quindi possiamo anche scrivere la funzione sopra come
!function (){}()
Entrambi sono comunque funzioni auto invocanti e salviamo anche un byte. Invece di 2 personaggi (,)
abbiamo usato solo un personaggio!
! è un operatore NOT logico , è un operatore booleano che invertirà qualcosa al suo contrario.
Sebbene sia possibile ignorare le parentesi della funzione invocata utilizzando BANG (!) Prima della funzione, invertirà comunque il ritorno, che potrebbe non essere quello desiderato. Come nel caso di un IEFE, ritornerebbe indefinito , che quando invertito diventa il vero booleano.
Utilizzare invece la parentesi di chiusura e il BANG ( ! ) Se necessario.
// 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
Altri operatori che funzionano ...
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
Operatori combinati ...
+!(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
Il punto esclamativo rende qualsiasi funzione restituisce sempre un valore booleano.
Il valore finale è la negazione del valore restituito dalla funzione.
!function bool() { return false; }() // true
!function bool() { return true; }() // false
Omettere !
negli esempi sopra sarebbe un SyntaxError .
function bool() { return true; }() // SyntaxError
Tuttavia, un modo migliore per raggiungere questo obiettivo sarebbe:
(function bool() { return true; })() // true
!
cambia il modo in cui il runtime analizza la funzione. Fa in modo che il runtime tratti la funzione come espressione di funzione (e non come una dichiarazione). Lo fa per consentire allo sviluppatore di invocare immediatamente la funzione utilizzando la ()
sintassi. !
si applicherà anche (cioè negazione) al risultato dell'invocazione dell'espressione della funzione.
È un altro modo di scrivere IIFE (espressione di funzione immediatamente invocata).
L'altro modo di scrivere -
(function( args ) {})()
uguale a
!function ( args ) {}();
(function (args) {...})()
sintassi più esplicita e lascerei quel !function
modulo agli strumenti di minimizzazione e offuscamento.
!
annullerà (al contrario) qualunque cosa tu ti aspetti di conseguenza, cioè se hai
var boy = true;
undefined
boy
true
!boy
false
quando chiami boy
, il tuo risultato sarà true
, ma nel momento in cui aggiungi il !
quando chiami boy
, cioè il !boy
tuo risultato sarà false
. Che in altre parole vuoi dire NotBoy , ma questa volta è fondamentalmente un risultato booleano, o true
o false
.
È la stessa cosa che accade !function () {}();
all'espressione, l'esecuzione solo function () {}();
ti segnalerà un errore, ma aggiungendolo !
proprio davanti alla tua function () {}();
espressione, lo rende l'opposto di quello function () {}();
che dovrebbe restituirti true
. Di seguito è riportato un esempio:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true