Autant de réponses qui font la moitié du travail. Oui, !!X
pourrait être lu comme "la véracité de X [représentée comme un booléen]". Mais !!
n'est pas, pratiquement parlant, si important pour déterminer si une seule variable est (ou même si plusieurs variables sont) véridiques ou fausses. !!myVar === true
est le même que juste myVar
. La comparaison !!X
avec un "vrai" booléen n'est pas vraiment utile.
Ce que vous gagnez, !!
c'est la possibilité de vérifier la véracité de plusieurs variables les unes par rapport aux autres de manière reproductible, standardisée (et compatible avec JSLint).
Simplement lancer :(
C'est...
0 === false
est false
.
!!0 === false
est true
.
Ce qui précède n'est pas si utile. if (!0)
vous donne les mêmes résultats que if (!!0 === false)
. Je ne peux pas penser à un bon cas pour convertir une variable en booléen, puis comparer à un "vrai" booléen.
Voir "== et! =" Dans les instructions de JSLint (note: Crockford déplace un peu son site; ce lien est susceptible de mourir à un moment donné) pour un peu sur pourquoi:
Les opérateurs == et! = Saisissent la coercition avant de comparer. Ceci est mauvais car cela rend vrai '\ t \ r \ n' == 0. Cela peut masquer des erreurs de type. JSLint ne peut pas déterminer de manière fiable si == est utilisé correctement, il est donc préférable de ne pas utiliser du tout == et! = Et de toujours utiliser les opérateurs === et! == les plus fiables à la place.
Si vous vous souciez seulement de la véracité ou de la fausseté d'une valeur, utilisez le formulaire court. Au lieu de
(foo != 0)
dis le
(foo)
et au lieu de
(foo == 0)
dire
(!foo)
Notez qu'il existe des cas non intuitifs où un booléen sera converti en un nombre ( true
est converti en 1
et false
en 0
) lors de la comparaison d'un booléen en un nombre. Dans ce cas, !!
pourrait être mentalement utile. Bien que, encore une fois, ce sont des cas où vous comparez un non-booléen à un booléen dur, ce qui est, imo, une grave erreur. if (-1)
est toujours le chemin à parcourir ici.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ 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
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
Et les choses deviennent encore plus folles selon votre moteur. WScript, par exemple, remporte le prix.
function test()
{
return (1 === 1);
}
WScript.echo(test());
En raison de l' historique jive de Windows , cela produira -1 dans une boîte de message! Essayez-le dans une invite cmd.exe et voyez! Mais WScript.echo(-1 == test())
vous donne toujours 0, ou WScript false
. Détourne le regard. C'est hideux.
Comparaison de la véracité :)
Mais que se passe-t-il si j'ai deux valeurs dont je dois vérifier la véracité / la fausseté égales?
Imaginez que nous avons myVar1 = 0;
et myVar2 = undefined;
.
myVar1 === myVar2
est 0 === undefined
et est évidemment faux.
!!myVar1 === !!myVar2
est !!0 === !!undefined
et est vrai! Même vérité! (Dans ce cas, les deux "ont une vérité de fausseté".)
Donc, le seul endroit où vous auriez vraiment besoin d'utiliser des "variables booléennes" serait si vous aviez une situation où vous vérifiez si les deux variables ont la même véracité, non? C'est-à-dire, utilisez !!
si vous avez besoin de voir si deux vars sont à la fois véridiques ou fausses (ou non), c'est-à-dire de véracité égale (ou non) .
Je ne peux pas penser à un excellent cas d'utilisation non artificiel pour cette désinvolture. Vous avez peut-être des champs "liés" dans un formulaire?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
Alors maintenant, si vous avez une vérité pour les deux ou une fausse pour le nom et l'âge du conjoint, vous pouvez continuer. Sinon, vous n'avez qu'un seul champ avec une valeur (ou un mariage arrangé très tôt) et devez créer une erreur supplémentaire sur votre errorObjects
collection.
EDIT 24 oct 2017, 6 fév 19:
Bibliothèques tierces qui attendent des valeurs booléennes explicites
Voici un cas intéressant ... !!
pourrait être utile lorsque des bibliothèques tierces attendent des valeurs booléennes explicites.
Par exemple, False dans JSX (React) a une signification spéciale qui n'est pas déclenchée par une simple fausseté. Si vous avez essayé de renvoyer quelque chose comme ce qui suit dans votre JSX, en attendant un int dans messageCount
...
{messageCount && <div>You have messages!</div>}
... vous pourriez être surpris de voir React effectuer un rendu 0
lorsque vous n'avez aucun message. Vous devez explicitement retourner false pour que JSX ne soit pas rendu. L'instruction ci-dessus renvoie 0
, que JSX rend avec bonheur, comme il se doit. Cela ne peut pas dire que vous n'en aviez pas Count: {messageCount && <div>Get your count to zero!</div>}
(ou quelque chose de moins artificiel).
Une solution implique le bangbang, qui coercé 0
en !!0
, qui est false
:
{!!messageCount && <div>You have messages!</div>}
Les documents de JSX vous suggèrent d'être plus explicite, d'écrire du code auto-commenté et d'utiliser une comparaison pour forcer à un booléen.
{messageCount > 0 && <div>You have messages!</div>}
Je suis plus à l'aise pour gérer moi-même la fausseté avec un ternaire -
{messageCount ? <div>You have messages!</div> : false}
Même chose dans Typescript: si vous avez une fonction qui retourne un booléen (ou si vous assignez une valeur à une variable booléenne), vous [généralement] ne pouvez pas retourner / assigner une valeur booléenne-y; ce doit être un booléen fortement typé. Cela signifie que si siff myObject
est fortement typé , return !myObject;
fonctionne pour une fonction renvoyant un booléen, mais return myObject;
ne le fait pas. Vous devez return !!myObject
correspondre aux attentes de Typescript.
L'exception pour Typescript? Si myObject
c'était un any
, vous êtes de retour dans le Wild West de JavaScript et pouvez le renvoyer sans !!
, même si votre type de retour est un booléen.
Gardez à l'esprit que ce sont des conventions JSX et Typescript , pas celles inhérentes à JavaScript .
Mais si vous voyez des 0
s étranges dans votre JSX rendu, pensez à une gestion de fausseté lâche.