loading...
Cover image for JavaScript: Double Not Operator?

JavaScript: Double Not Operator?

will_devs profile image Will Harris Originally published at bikesandbytes.net ・1 min read

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).

Posted on May 24 by:

will_devs profile

Will Harris

@will_devs

Developer currently focused on React, TypeScript, and GatsbyJS.

Discussion

markdown guide
 

It’s commonly called ‘bang bang’

 

Bang bang! You're Boolean now!

 
Sloan, the sloth mascot Comment marked as low quality/non-constructive by the community View code of conduct

Which sounds eerily similar to "gang bang" ;)

 

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).

 

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