DEV Community

Cover image for JavaScript: Double Not Operator?
Will Harris
Will Harris

Posted on • Edited on • Originally published at bikesandbytes.net

JavaScript: Double Not Operator?

Article originally published on Will’s personal blog


Here's a little JavaScript tidbit I learned about recently.

The ! operator is a familiar face in the JavaScript landscape, showing up when we need to negate a value.

let thing = true
thing = !thing
thing === false // true

Here we take a Boolean value (true) and invert it to the opposite value (false).

This also works with non-Boolean values as well, since all values in JavaScript are either truthy or falsy.

let thing = "This string is truthy!"
thing = !thing
thing === false // true

Here we can see how the ! operator casts the value from a string value (truthy) to it's opposite Boolean value false. The same conversion happens when we use the ! operator on any value in JavaScript. If the value is already truthy it is cast to false, and vice versa.

It follows then that !! just performs this inversion twice.

let thing = "This string is truthy!"
thing = !!thing
thing === true // true

This is really just a shorter way to cast a value to it's Boolean counterpart. If a value is already falsy, using !! will result in the value being cast to false.

We could just as well do this for the same result:

let thing = Boolean("This string is truthy!")
thing === true // true

What's the difference? As far as I can tell, there is none!

Although !! is more succinct, the argument could be made that it is more confusing syntactically than Boolean(value).

Top comments (5)

Collapse
 
hale_sai profile image
Mick

It’s commonly called ‘bang bang’

Collapse
 
adamtokarski profile image
Adam Tokarski

Bang bang! You're Boolean now!

Collapse
 
leob profile image
Comment marked as low quality/non-constructive by the community. View Code of Conduct
leob

Which sounds eerily similar to "gang bang" ;)

Collapse
 
leob profile image
leob • Edited

Yes this is a well-known JS idiom, you see it a lot in JS source code. Goes to show what a quirky language JS really is (what you see is that newer versions of JS like ES2015 are trying to clean up & rationalize the language, at least that's my interpretation of it).

Collapse
 
willsmart profile image
willsmart • Edited

The bitwise NOT operator can be used as a poor-mans integer cast. I don't know what they call it but I'm really hoping it's "squiggiggle"
~~value effectively replaces Math.trunc(Number(value) || 0)

I have to add that it's clearly a confusing hack. They're both hacks. If you want a boolean from a value, please use Boolean(value). Do it for your readers.

Squiggiggle essentially casts its input to a 32-bit signed integer (truncating decimals toward 0), or 0 if there was no reasonable integer to choose...

> ~~0
< 0
> ~~false
< 0
> ~~true
< 1
> ~~10101
< 10101
> ~~"100"
< 100

Decimals...

> ~~1.1
< 1
> ~~1.9999
< 1
> ~~ -1.9999
< -1
> ~~ -1.1
< -1
// Integer zeros don't have signs, so sqiggiggle flattens -0 down to 0:
> ~~ -0
< 0

Non-numbers work as you might expect...

> ~~"Fred"
< 0
> ~~{}
< 0
> ~~[]
< 0
> ~~null
< 0
> ~~undefined
< 0
> ~~NaN
< 0
> ~~Symbol()
< VM699:1 Uncaught TypeError: Cannot convert a Symbol value to a number

But be careful if you're passing in large numbers, as they will be clipped to a 32 bit signed integer.

> ~~(2**29)
< 536870912
> ~~(2**30)
< 1073741824
> ~~(2**31)
< -2147483648
> ~~(2**32)
< 0

-~number is a fun one to play with too, a bit useless but a good exercise in 2's complement for any teachers out there.

-~ -2
-1
-~ -1
-0
-~0
1
-~1
2

Some comments may only be visible to logged-in visitors. Sign in to view all comments.