I saw some code that seems to use an operator I don't recognize, in the form of two exclamation points, like so: !!
. Can someone please tell me what this operator does?
The context in which I saw this was,
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
! is "boolean not", which essentially typecasts the value of "enable" to its boolean opposite. The second ! flips this value. So,
!!enable
means "not not enable," giving you the value ofenable
as a boolean.It seems that the
!!
operator results in a double negation.I think worth mentioning is, that a condition combined with logical AND/OR will not return a boolean value but last success or first fail in case of && and first success or last fail in case of || of condition chain.
In order to cast the condition to a true boolean literal we can use the double negation:
After seeing all these great answers, I would like to add another reason for using
!!
. Currenty I'm working in Angular 2-4 (TypeScript) and I want to return a boolean asfalse
when my user is not authenticated. If he isn't authenticated, the token-string would benull
or""
. I can do this by using the next block of code:I suspect this is a leftover from C++ where people override the ! operator but not the bool operator.
So to get a negative(or positive) answer in that case you would first need to use the ! operator to get a boolean, but if you wanted to check the positive case would use !!.
So many answers doing half the work. Yes,
!!X
could be read as "the truthiness of X [represented as a boolean]". But!!
isn't, practically speaking, so important for figuring out whether a single variable is (or even if many variables are) truthy or falsy.!!myVar === true
is the same as justmyVar
. Comparing!!X
to a "real" boolean isn't really useful.What you gain with
!!
is the ability to check the truthiness of multiple variables against each other in a repeatable, standardized (and JSLint friendly) fashion.Simply casting :(
That is...
0 === false
isfalse
.!!0 === false
istrue
.The above's not so useful.
if (!0)
gives you the same results asif (!!0 === false)
. I can't think of a good case for casting a variable to boolean and then comparing to a "true" boolean.See "== and !=" from JSLint's directions (note: Crockford is moving his site around a bit; that link is liable to die at some point) for a little on why:
Note that there are some unintuitive cases where a boolean will be cast to a number (
true
is cast to1
andfalse
to0
) when comparing a boolean to a number. In this case,!!
might be mentally useful. Though, again, these are cases where you're comparing a non-boolean to a hard-typed boolean, which is, imo, a serious mistake.if (-1)
is still the way to go here.And things get even crazier depending on your engine. WScript, for instance, wins the prize.
Because of some historical Windows jive, that'll output -1 in a message box! Try it in a cmd.exe prompt and see! But
WScript.echo(-1 == test())
still gives you 0, or WScript'sfalse
. Look away. It's hideous.Comparing truthiness :)
But what if I have two values I need to check for equal truthi/falsi-ness?
Pretend we have
myVar1 = 0;
andmyVar2 = undefined;
.myVar1 === myVar2
is0 === undefined
and is obviously false.!!myVar1 === !!myVar2
is!!0 === !!undefined
and is true! Same truthiness! (In this case, both "have a truthiness of falsy".)So the only place you'd really need to use "boolean-cast variables" would be if you had a situation where you're checking if both variables have the same truthiness, right? That is, use
!!
if you need to see if two vars are both truthy or both falsy (or not), that is, of equal (or not) truthiness.I can't think of a great, non-contrived use case for that offhand. Maybe you have "linked" fields in a form?
So now if you have a truthy for both or a falsy for both spouse name and age, you can continue. Otherwise you've only got one field with a value (or a very early arranged marriage) and need to create an extra error on your
errorObjects
collection.EDIT 24 Oct 2017:
3rd party libraries that expect explicit Boolean values
Here's an interesting case...
!!
might be useful when 3rd party libs expect explicit Boolean values.For instance, False in JSX (React) has a special meaning that's not triggered on simple falsiness. If you tried returning something like the following in your JSX, expecting an int in
messageCount
...{messageCount && <div>You have messages!</div>}
... you might be surprised to see React render a
0
when you have zero messages. You have to explicitly return false for JSX not to render. The above statement returns0
, which JSX happily renders, as it should. It can't tell you didn't haveCount: {messageCount && <div>Get your count to zero!</div>}
(or something less contrived).One fix involves the bangbang, which coerces
0
into!!0
, which isfalse
:{!!messageCount && <div>You have messages!</div>}
JSX' docs suggest you be more explicit, write self-commenting code, and use a comparison to force to a Boolean.
{messageCount > 0 && <div>You have messages!</div>}
I'm more comfortable handling falsiness myself with a ternary --
{messageCount ? <div>You have messages!</div> : false}
Keep in mind that this is a JSX convention, not one inherent to JavaScript.
But if you see strange
0
s in your rendered JSX, think loose falsy management.