Così tante risposte facendo metà del lavoro. Sì, !!X
potrebbe essere letto come "la verità di X [rappresentato come un booleano]". Ma !!
, in pratica, non è così importante per capire se una singola variabile è (o anche se molte variabili lo sono) verità o falsità. !!myVar === true
è lo stesso di solo myVar
. Il confronto !!X
con un "vero" booleano non è davvero utile.
Ciò che ottieni !!
è la capacità di verificare la veridicità di più variabili l'una contro l'altra in modo ripetibile, standardizzato (e compatibile con JSLint).
Semplicemente casting :(
Questo è...
0 === false
lo è false
.
!!0 === false
lo è true
.
Quanto sopra non è così utile. if (!0)
ti dà gli stessi risultati di if (!!0 === false)
. Non riesco a pensare a un buon caso per lanciare una variabile in booleano e poi confrontarla con un "vero" booleano.
Vedi "== e! =" Dalle indicazioni di JSLint (nota: Crockford sta spostando un po 'il suo sito; quel collegamento rischia di morire ad un certo punto) per un po' del perché:
Gli operatori == e! = Digitano la coercizione prima del confronto. Questo è male perché causa '\ t \ r \ n' == 0 per essere vero. Questo può mascherare errori di tipo. JSLint non è in grado di determinare in modo affidabile se == viene utilizzato correttamente, quindi è meglio non utilizzare == e! = Affatto e utilizzare sempre gli operatori === e! == più affidabili.
Se ti interessa solo che un valore sia veritiero o falso, usa la forma abbreviata. Invece di
(foo != 0)
basta dire
(foo)
e invece di
(foo == 0)
dire
(!foo)
Nota che ci sono alcuni casi non intuitivi in cui un booleano verrà lanciato su un numero ( true
viene lanciato su 1
e false
verso 0
) quando si confronta un booleano con un numero. In questo caso, !!
potrebbe essere mentalmente utile. Anche se, di nuovo, questi sono casi in cui stai confrontando un non booleano con un booleano duro, che è, imo, un grave errore. if (-1)
è ancora la strada da percorrere qui.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ Original ║ Equivalent ║ Result ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam") ║ if (-1 == 1) ║ undefined ║
║ if (-1 == false) console.log("spam") ║ if (-1 == 0) ║ undefined ║
║ Order doesn't matter... ║ ║ ║
║ if (true == -1) console.log("spam") ║ if (1 == -1) ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam") ║ if (truthy) ║ spam ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
E le cose diventano ancora più folli a seconda del tuo motore. WScript, ad esempio, vince il premio.
function test()
{
return (1 === 1);
}
WScript.echo(test());
A causa di alcuni jive di Windows storici , verrà visualizzato -1 in una finestra di messaggio! Provalo nel prompt di cmd.exe e guarda! Ma WScript.echo(-1 == test())
ti dà ancora 0, o WScript false
. Distogliere lo sguardo. È orribile.
Confrontando la verità :)
Ma cosa succede se ho due valori che devo verificare per uguale truthi / falsità?
Fai finta di avere myVar1 = 0;
e myVar2 = undefined;
.
myVar1 === myVar2
è 0 === undefined
ed è ovviamente falso.
!!myVar1 === !!myVar2
è !!0 === !!undefined
ed è vero! Stessa verità! (In questo caso, entrambi "hanno una verità di falsità".)
Quindi l'unico posto in cui avresti davvero bisogno di usare "variabili booleane cast" sarebbe se avessi una situazione in cui stai controllando se entrambe le variabili hanno la stessa veridicità, giusto? Cioè, usa !!
se hai bisogno di vedere se due vars sono entrambi veritieri o entrambi falsi (o no), cioè di uguale (o no) verità .
Non riesco a pensare a un caso d'uso eccezionale e non inventato per questo fuori mano. Forse hai campi "collegati" in un modulo?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
Quindi ora se hai una verità per entrambi o una falsità sia per il nome del coniuge che per l'età, puoi continuare. Altrimenti hai solo un campo con un valore (o un matrimonio organizzato molto presto) e devi creare un errore extra sulla tua errorObjects
collezione.
MODIFICA 24 ott 2017, 6 febbraio 19:
Librerie di terze parti che prevedono valori booleani espliciti
Ecco un caso interessante ... !!
potrebbe essere utile quando le librerie di terze parti prevedono valori booleani espliciti.
Ad esempio, False in JSX (React) ha un significato speciale che non è innescato da una semplice falsità. Se hai provato a restituire qualcosa di simile al seguente nel tuo JSX, aspettandoti un int in messageCount
...
{messageCount && <div>You have messages!</div>}
... potresti essere sorpreso di vedere React render a 0
quando hai zero messaggi. Devi restituire esplicitamente false per non eseguire il rendering di JSX. Restituisce la precedente dichiarazione 0
, che JSX rende felicemente, come dovrebbe. Non posso dire che non hai avuto Count: {messageCount && <div>Get your count to zero!</div>}
(o qualcosa di meno inventato).
Una correzione comporta la bangbang, che costringe 0
in !!0
, che è false
:
{!!messageCount && <div>You have messages!</div>}
I documenti di JSX suggeriscono di essere più espliciti, scrivere codice di auto-commento e utilizzare un confronto per forzare un valore booleano.
{messageCount > 0 && <div>You have messages!</div>}
Mi sento più a mio agio nel maneggiare la falsità con un ternario -
{messageCount ? <div>You have messages!</div> : false}
Stesso affare in Typescript: se hai una funzione che restituisce un valore booleano (o stai assegnando un valore a una variabile booleana), [di solito] non puoi restituire / assegnare un valore booleano-y; deve essere un booleano fortemente tipizzato. Questo significa che, se if myObject
è fortemente tipizzato , return !myObject;
funziona per una funzione che restituisce un valore booleano, ma return myObject;
non lo fa. Devi return !!myObject
soddisfare le aspettative di Typescript.
L'eccezione per Typescript? Se myObject
era un any
, sei tornato nel selvaggio West di JavaScript e puoi restituirlo senza !!
, anche se il tuo tipo di ritorno è un valore booleano.
Tieni presente che si tratta di convenzioni JSX e Typescript , non inerenti a JavaScript .
Ma se vedi strani 0
s nel tuo JSX renderizzato, pensa alla falsa gestione.