By Hexagon Theory


2009-04-24 08:13:58 8 Comments

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;

30 comments

@Lakmal 2019-10-29 19:56:49

To cast your JavaScript variables to boolean,

var firstname = "test";
//type of firstname is string
var firstNameNotEmpty = !!firstname;
//type of firstNameNotEmpty is boolean

javascript false for "",0,undefined and null

javascript is true for number other then zero,not empty strings,{},[] and new Date() so,

!!("test") /*is true*/
!!("") /*is false*/

@Alireza 2017-06-24 04:16:23

!! it's using NOT operation twice together, ! convert the value to a boolean and reverse it, here is a simple example to see how !! works:

At first, the place you have:

var zero = 0;

Then you do !0, it will be converted to boolean and be evaluated to true, because 0 is falsy, so you get the reversed value and converted to boolean, so it gets evaluated to true.

!zero; //true

but we don't want the reversed boolean version of the value, so we can reverse it again to get our result! That's why we use another !.

Basically, !! make us sure, the value we get is boolean, not falsy, truthy or string etc...

So it's like using Boolean function in javascript, but easy and shorter way to convert a value to boolean:

var zero = 0;
!!zero; //false

@Ryan Taylor 2016-10-19 21:00:36

I just wanted to add that

if(variableThing){
  // do something
}

is the same as

if(!!variableThing){
  // do something
}

But this can be an issue when something is undefined.

// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};

// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar

a.foo 
b.foo.bar

// This works -- these return undefined

a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar

The trick here is the chain of &&s will return the first falsey value it finds -- and this can be fed to an if statement etc. So if b.foo is undefined, it will return undefined and skip the b.foo.bar statement, and we get no error.

The above return undefined but if you have an empty string, false, null, 0, undefined those values will return and soon as we encounter them in the chain -- [] and {} are both "truthy" and we will continue down the so-called "&& chain" to the next value to the right.

P.S. Another way of doing the same thing is (b || {}).foo, because if b is undefined then b || {} will be {}, and you'll be accessing a value in an empty object (no error) instead of trying to access a value within "undefined" (causes an error). So, (b || {}).foo is the same as b && b.foo and ((b || {}).foo || {}).bar is the same as b && b.foo && b.foo.bar.

@Ryan Taylor 2017-01-10 17:36:42

good point -- changed my answer. It only happens on an object when it's nested three levels deep, because like you said ({}).anything will give undefined

@Weijing Jay Lin 2019-07-20 00:03:38

I think your answer should get higher vote

@Kirby L. Wallace 2019-03-10 18:43:26

This question has been answered quite thoroughly, but I'd like to add an answer that I hope is as simplified as possible, making the meaning of !! as simple to grasp as can be.

Because javascript has what are called "truthy" and "falsey" values, there are expressions that when evaluated in other expressions will result in a true or false condition, even though the value or expression being examined is not actually true or false.

For instance:

if (document.getElementById('myElement')) {
    // code block
}

If that element does in fact exist, the expression will evaluate as true, and the code block will be executed.

However:

if (document.getElementById('myElement') == true) {
    // code block
}

...will NOT result in a true condition, and the code block will not be executed, even if the element does exist.

Why? Because document.getElementById() is a "truthy" expression that will evaluate as true in this if() statement, but it is not an actual boolean value of true.

The double "not" in this case is quite simple. It is simply two nots back to back.

The first one simply "inverts" the truthy or falsey value, resulting in an actual boolean type, and then the second one "inverts" it back again to it's original state, but now in an actual boolean value. That way you have consistency:

if (!!document.getElementById('myElement')) {}

and

if (!!document.getElementById('myElement') == true) {}

will BOTH return true, as expected.

@stevehipwell 2009-04-24 08:18:07

Coerces oObject to boolean. If it was falsey (e.g. 0, null, undefined, etc.), it will be false, otherwise, true.

!oObject  //Inverted boolean
!!oObject //Non inverted boolean so true boolean representation

So !! is not an operator, it's just the ! operator twice.

Real World Example "Test IE version":

let isIE8 = false;  
isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);  
console.log(isIE8); // returns true or false 

If you ⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));  
// returns either an Array or null  

but if you ⇒

console.log(!!navigator.userAgent.match(/MSIE 8.0/));  
// returns either true or false

@Chuck 2009-04-24 17:14:18

It converts a nonboolean to an inverted boolean (for instance, !5 would be false, since 5 is a non-false value in JS), then boolean-inverts that so you get the original value as a boolean (so !!5 would be true).

@Micah Snyder 2009-04-24 18:27:27

An easy way to describe it is: Boolean(5) === !!5; Same casting, fewer characters.

@thetoolman 2012-07-16 03:53:22

This is used to convert truthy values to boolean true, and falsy values too boolean false.

@Yaroslav 2012-10-22 12:38:40

Found this obscure notation on a Magento php code, thought that could be two separate not operators but was non confident. This answer and some other comments clarified things for me

@victorvartan 2013-02-03 12:24:32

@Micah Snyder be careful that in JavaScript it's better to use boolean primitives instead of creating objects that box booleans with new Boolean(). Here's an example to see the difference: jsfiddle.net/eekbu

@rds 2014-03-26 19:43:13

As far as I know, this bang-bang pattern is not useful inside a if(…_ statement; only in a return statement of a function that should return a boolean.

@Azder 2014-05-28 05:57:48

This Boolean(5) === !!5 is not correct: the browers will evaluate to true but Boolean(5) returns a Boolean object, and !!5 returns a boolean literal. When evaluated browsers will wrap/unwrap the literal with object, but typeof will return 'object' for the first one, and 'boolean' for the second.

@Pierpaolo 2014-07-19 11:12:20

@Azder: I've tried both typeof(Boolean(5)) and typeof(!!5) in Chrome, Firefox and IE8 (in the console of all the three) and they all return 'boolean'

@Azder 2014-07-24 05:36:26

My bad, I was thinking of new Boolean(5) which is not the case here. If anything, this kind of confusion is a good reason not to use the constructor as a function, but double negation (!!)

@Gavin Jackson 2014-09-18 12:20:39

@Stevo3000 - it's not the wrong way around, just incomplete... 'it converts a non-boolean to a boolean and inverts it, then inverts it again.'

@TranslucentCloud 2016-11-28 18:53:04

All browsers which support ! support !!. Because it is not an operator, it is a pair of operators.

@geofflee 2017-03-02 00:33:15

@sparkyShorts, if your code uses === to compare boolean values, then you must type cast "truthy" values to booleans using !!, otherwise your results will be wrong. For example, assuming 0 indicates false and 1 indicates true, then 1 === true will fail, whereas !!1 === true works correctly.

@Dale Harris 2018-03-20 17:15:20

@sparkyShorts Another example: Consider a property on an object obj.myString that could have a string value, but could also be an empty string, null, or undefined. It's much less code (albeit more obscure) to write if (!!obj.myString) { doSomething() }; than it is to write if (typeof obj.myString !== 'undefined' && obj.myString !== null && obj.myString !== '') { doSomething() };

@Gerd 2018-07-24 09:16:15

Boolean("") === !!"" But !!"" is shorter. This it's only a creation of the shorthand coding people. 20 years ago if developers saw such code in perl, they sayed it's ugly and unreadable. Today this style of code is cool and accepted form the community. Times are changing! In 20 years it is ugly again.

@darelf 2018-08-30 19:50:00

@DaleHarris that's not true at all. An object key that's missing, is null an empty string, or any of the other "falsy" values will evaluate as false in an if () statement.

@Dale Harris 2018-09-01 03:02:10

@darelf Yep, my bad. Inside an if statement is a bad example. A more likely use case is assigning a boolean, like... var hasString = !!obj.myString;

@Marcus Hiles 2019-02-18 11:30:02

Wow. This explanation was great. Got me right. Thanks

@tolotra 2019-02-06 14:10:16

Double ! evaluate a variable to it's boolean value. Eg: false 0 (zero), '' or "" (empty string), null, undefined, NaN is evaluated to false. See this post https://www.sitepoint.com/javascript-truthy-falsy/

@ruffin 2015-04-29 18:14:43

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 just myVar. 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 is false.
  • !!0 === false is true.

The above's not so useful. if (!0) gives you the same results as if (!!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:

The == and != operators do type coercion before comparing. This is bad because it causes ' \t\r\n' == 0 to be true. This can mask type errors. JSLint cannot reliably determine if == is being used correctly, so it is best to not use == and != at all and to always use the more reliable === and !== operators instead.

If you only care that a value is truthy or falsy, then use the short form. Instead of
(foo != 0)

just say
(foo)

and instead of
(foo == 0)

say
(!foo)

Note that there are some unintuitive cases where a boolean will be cast to a number (true is cast to 1 and false to 0) 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.

╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║               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
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝

And things get even crazier depending on your engine. WScript, for instance, wins the prize.

function test()
{
    return (1 === 1);
}
WScript.echo(test());

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's false. 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; and myVar2 = undefined;.

  • myVar1 === myVar2 is 0 === 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?

if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
    errorObjects.spouse = "Please either enter a valid name AND age " 
        + "for your spouse or leave all spouse fields blank.";
}

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, 6 Feb 19:

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 returns 0, which JSX happily renders, as it should. It can't tell you didn't have Count: {messageCount && <div>Get your count to zero!</div>} (or something less contrived).

  • One fix involves the bangbang, which coerces 0 into !!0, which is false:
    {!!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}

Same deal in Typescript: If you have a function that returns a boolean (or you're assigning a value to a boolean variable), you [usually] can't return/assign a boolean-y value; it has to be a strongly typed boolean. This means, iff myObject is strongly typed, return !myObject; works for a function returning a boolean, but return myObject; doesn't. You have to return !!myObject to match Typescript's expectations.

The exception for Typescript? If myObject was an any, you're back in JavaScript's Wild West and can return it without !!, even if your return type is a boolean.

Keep in mind that these are JSX & Typescript conventions, not ones inherent to JavaScript.

But if you see strange 0s in your rendered JSX, think loose falsy management.

@jk7 2015-05-06 20:41:37

Good explanation. So would you say the !! is not strictly necessary in this Worker feature detection example? if (!!window.Worker)

@ruffin 2015-05-06 20:54:57

Nope, you wouldn't need it. Truthiness and true "externally" operate exactly the same in an if. I keep trying, but I can't think of a reason to prefer casting truthiness to a boolean value outside of the sort of convoluted "compare truthinesses" case, above, except for readability if you reuse the value later, as in the q library example. But even then, it's a information-lossy shortcut, and I'd argue you're better off evaluating truthiness each time.

@Alexander Pritchard 2018-07-28 23:02:49

React is the main reason we've started using the !! pattern, but it happens to be a very convenient and repeatable thing. I only have to worry about the truthiness or falseyness of something, not what the underlying type is.

@ruffin 2019-01-03 21:51:27

Downvotes without comments make it difficult to address your concern! Let me know what looks bad, and I'll be happy to address it.

@مهدی عابدی برنامه نویس و مشاور 2018-09-15 04:37:21

Sometimes it is necessary to check whether we have a value in the function or not, and the amount itself is not important to us, but whether or not it matters. for example we want to check ,if user has major or not and we have a function just like:

hasMajor(){return this.major}//it return "(users major is)Science" 

but the answer is not important to us we just want to check it has a major or not and we need a boolean value(true or false) how we get it:

just like this:

hasMajor(){ return !(!this.major)}

or as the same

hasMajor(){return !!this.major)}

if this.major has a value then !this.major return false but because the value has exits and we need to return true we use ! twice to return the correct answer !(!this.major)

@Khuong 2018-07-25 03:52:52

It forces all things to boolean.

For example:

console.log(undefined); // -> undefined
console.log(!undefined); // -> true
console.log(!!undefined); // -> false

console.log('abc'); // -> abc
console.log(!'abc'); // -> false
console.log(!!'abc'); // -> true

console.log(0 === false); // -> undefined
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true

@efkan 2017-07-11 07:03:50

Returns boolean value of a variable.

Instead, Boolean class can be used.

(please read code descriptions)

var X = "test"; // X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value beacuse non-empty strings evaluates as `true` in boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // writes `true`

Namely, Boolean(X) = !!X in use.

Please check code snippet out below

let a = 0
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a) // writes '0 is NOT true in boolean' value as boolean - So that's true.In boolean 0 means false and 1 means true.
console.log("!!a: ", !!a) // writes 0 value in boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // equals to `!!a`
console.log("\n") // newline

a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes 1 value in boolean
console.log("\n") // newline

a = ""
console.log("a: ", a)
console.log("!a: ", !a) // writes '"" is NOT true in boolean' value as boolean - So that's true.In boolean empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // writes "" value in boolean
console.log("\n") // newline

a = "test"
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes "test" value in boolean

console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true

@Mystical 2017-04-17 14:47:47

!! is similar to using the Boolean constructor, or arguably more like the Boolean function.

console.log(Boolean(null)); // Preffered over the Boolean object

console.log(new Boolean(null).valueOf()); // Not recommended for coverting non-boolean values

console.log(!!null); // A hacky way to omit calling the Boolean function, but essentially does the same thing. 


// The context you saw earlier (your example)
var vertical;

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical; 
        // Let's break it down: If vertical is strictly not undefined, return the boolean value of vertical and set it to this.vertical. If not, don't set a value for this.vertical (just ignore it and set it back to what it was before; in this case, nothing).   

        return this.vertical;
}

console.log( "\n---------------------" )

// vertical is currently undefined

console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = 12.5; // set vertical to 12.5, a truthy value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be true anyway
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = -0; // set vertical to -0, a falsey value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be false either way
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

Falsey values in javascript coerce to false, and truthy values coerce to true. Falsey and truthy values can also be used in if statements and will essentially "map" to their corresponding boolean value. However, you will probably not find yourself having to use proper boolean values often, as they mostly differ in output (return values).

Although this may seem similar to casting, realistically this is likely a mere coincidence and is not 'built' or purposely made for and like a boolean cast. So let's not call it that.


Why and how it works

To be concise, it looks something like this: ! ( !null ). Whereas, null is falsey, so !null would be true. Then !true would be false and it would essentially invert back to what it was before, except this time as a proper boolean value (or even vice versa with truthy values like {} or 1).


Going back to your example

Overall, the context that you saw simply adjusts this.vertical depending on whether or not vertical is defined, and if so; it will be set to the resulting boolean value of vertical, otherwise it will not change. In other words, if vertical is defined; this.vertical will be set to the boolean value of it, otherwise, it will stay the same. I guess that in itself is an example of how you would use !!, and what it does.


Vertical I/O Example

Run this example and fiddle around with the vertical value in the input. See what the result coerces to so that you can fully understand your context's code. In the input, enter any valid javascript value. Remember to include the quotations if you are testing out a string. Don't mind the CSS and HTML code too much, simply run this snippet and play around with it. However, you might want to take a look at the non-DOM-related javascript code though (the use of the Example constructor and the vertical variable).

var vertical = document.getElementById("vertical");
var p = document.getElementById("result");

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical;   

        return this.vertical;
}

document.getElementById("run").onclick = function()
{

  p.innerHTML = !!( new Example(eval(vertical.value)).vertical );
  
}
input
{
  text-align: center;
  width: 5em;
} 

button 
{
  margin: 15.5px;
  width: 14em;
  height: 3.4em;
  color: blue;
}

var 
{
  color: purple;
}

p {
  margin: 15px;
}

span.comment {
  color: brown;
}
<!--Vertical I/O Example-->
<h4>Vertical Example</h4>
<code id="code"><var class="var">var</var> vertical = <input type="text" id="vertical" maxlength="9" />; <span class="comment">// enter any valid javascript value</span></code>
<br />
<button id="run">Run</button>
<p id="result">...</p>

@Wouter Vanherck 2017-03-29 07:15:21

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 as false when my user is not authenticated. If he isn't authenticated, the token-string would be null or "". I can do this by using the next block of code:

public isAuthenticated(): boolean {
   return !!this.getToken();
}

@Abhay Dixit 2016-07-15 10:25:01

Use logical not operator two times
it means !true= false
and !!true = true

@GreQ 2016-05-25 10:18:34

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.

res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'

In order to cast the condition to a true boolean literal we can use the double negation:

res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true

@Damian Yerrick 2016-03-06 14:46:50

The if and while statements and the ? operator use truth values to determine which branch of code to run. For example, zero and NaN numbers and the empty string are false, but other numbers and strings are true. Objects are true, but the undefined value and null are both false.

The double negation operator !! calculates the truth value of a value. It's actually two operators, where !!x means !(!x), and behaves as follows:

  • If x is a false value, !x is true, and !!x is false.
  • If x is a true value, !x is false, and !!x is true.

When used at the top level of a Boolean context (if, while, or ?), the !! operator is behaviorally a no-op. For example, if (x) and if (!!x) mean the same thing.

Practical uses

However it has several practical uses.

One use is to lossily compress an object to its truth value, so that your code isn't holding a reference to a big object and keeping it alive. Assigning !!some_big_object to a variable instead of some_big_object lets go of it for the garbage collector. This is useful for cases that produce either an object or a false value such as null or the undefined value, such as browser feature detection.

Another use, which I mentioned in an answer about C's corresponding !! operator, is with "lint" tools that look for common typos and print diagnostics. For example, in both C and JavaScript, a few common typos for Boolean operations produce other behaviors whose output isn't quite as Boolean:

  • if (a = b) is assignment followed by use of the truth value of b; if (a == b) is an equality comparison.
  • if (a & b) is a bitwise AND; if (a && b) is a logical AND. 2 & 5 is 0 (a false value); 2 && 5 is true.

The !! operator reassures the lint tool that what you wrote is what you meant: do this operation, then take the truth value of the result.

A third use is to produce logical XOR and logical XNOR. In both C and JavaScript, a && b performs a logical AND (true if both sides are true), and a & b performs a bitwise AND. a || b performs a logical OR (true if at least one are true), and a | b performs a bitwise OR. There's a bitwise XOR (exclusive OR) as a ^ b, but there's no built-in operator for logical XOR (true if exactly one side is true). You might, for example, want to allow the user to enter text in exactly one of two fields. What you can do is convert each to a truth value and compare them: !!x !== !!y.

@Greg Gum 2015-12-04 12:50:49

!!x is shorthand for Boolean(x)

The first bang forces the js engine to run Boolean(x) but also has the side effect of inverting the value. So the second bang undoes the side effect.

@Salman A 2012-05-15 09:06:18

!!expr returns a Boolean value (true or false) depending on the truthiness of the expression. It makes more sense when used on non-boolean types. Consider these examples, especially the 3rd example and onward:

          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy

             !!"" === false // empty string is falsy
          !!"foo" === true  // non-empty string is truthy
        !!"false" === true  // ...even if it contains a falsy value

     !!window.foo === false // undefined is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!

@Camilo Martin 2012-12-18 08:05:51

Worth noting: !!new Boolean(false) // true

@Camilo Martin 2012-12-18 08:06:37

...But also !!Boolean(false) // false

@Salman A 2012-12-18 08:15:21

new Boolean(false) is an object and an object is truthy even if it contains a falsy value!

@Camilo Martin 2012-12-18 08:25:00

Yes I know, but consider the fact that most native constructors (String, Number, Date, etc) are meant to be callable as functions too, yet in this case the result is different!

@Salman A 2013-02-26 11:02:44

@CamiloMartin: just realized that new Boolean(false) returns an object while Boolean(false) returns the primitive false. Hope this makes sense.

@aikeru 2013-08-21 21:13:34

@SalmanA this confusing behavior leads me to avoid the native constructors altogether. Each one of them has a quirk or two.

@Ande 2014-06-24 12:47:31

Why cross out this text "!!expr converts any truthy expression into the boolean true (and false otherwise)"? Might lead people to believe that there's something wrong with that statement. (when there's actually nothing wrong with it)

@Salman A 2014-06-24 19:23:26

@Ande: I wanted to avoid the words "cast" and "convert". They might lead a person to believe that a variable itself is type-casted/type-juggled to a boolean.

@tobibeer 2015-10-10 18:45:51

@CamiloMartin, !!new String("") is also true, so what do you mean with your statement?

@Camilo Martin 2015-10-10 20:14:51

@tobibeer the link in "your statement" refers to a comment from someone other than me (typo?). If you are trying to understand !!new String(""), understand it is an object and not a string (new String returning a non-string is one of the amazing features of this fine language).

@Michael Nelson 2016-01-28 22:49:39

+1 because you used the word "truthiness". I tried to give you +2 because you italicized it, but it wouldn't let me.

@sam 2016-11-10 01:04:51

But also! !!(new Boolean(false)).valueOf() // false

@samazi 2017-01-29 21:05:55

@sam Yes, because by calling valueOf, you are retrieving the primitive value you supplied (false) you are essentially asking the javascript engine to perform 1. !false (which returns true), then 2. !true which returns... false

@RYS 2017-03-02 06:19:48

This is the best answer for my Python brain. 'truthiness' was the magic word for me.

@sam 2017-04-06 23:15:01

@SandorA I know, my point was: (1) never create a primitive with new; (2) if you do (1) anyway, never test it without valueOf

@Stephen S 2017-07-26 14:33:34

Note that [] is truthy, but [] == false. Therefore, !![] == true, but [] == false.

@Salman A 2017-07-27 06:57:31

@StephenS yes [] is truthy but [] == false because according to the rules you are doing [] == +0 -> "" == +0 -> +0 == +0 -> true. JavaScript works in mysterious ways.

@Navin Rauniyar 2014-04-09 04:29:23

The !! construct is a simple way of turning any JavaScript expression into its Boolean equivalent.

For example: !!"he shot me down" === true and !!0 === false.

@ruffin 2015-04-29 17:38:22

Very close to the important distinction. Key is that 0 === false is false and !!0 === false is true.

@GibboK 2015-07-01 07:29:12

Some operators in JavaScript perform implicit type conversions, and are sometimes used for type conversion.

The unary ! operator converts its operand to a boolean and negates it.

This fact lead to the following idiom that you can see in your source code:

!!x // Same as Boolean(x). Note double exclamation mark

@JeevanReddy Avanaganti 2015-03-04 08:25:35

here is a piece of code from angular js

var requestAnimationFrame = $window.requestAnimationFrame ||
                                $window.webkitRequestAnimationFrame ||
                                $window.mozRequestAnimationFrame;

 var rafSupported = !!requestAnimationFrame;

their intention is to set rafSupported to true or false based on the availability of function in requestAnimationFrame

it can be achieved by checking in following way in general:

if(typeof  requestAnimationFrame === 'function')
rafSupported =true;
else
rafSupported =false;

the short way could be using !!

rafSupported = !!requestAnimationFrame ;

so if requestAnimationFrame was assigned a function then !requestAnimationFrame would be false and one more ! of it would be true

if requestAnimationFrame was assinged undefined then !requestAnimationFrame would be true and one more ! of it would be false

@user3698272 2014-06-28 03:35:13

a = 1;
alert(!a) // -> false : a is not not defined
alert(!!a) // -> true : a is not not defined

For !a, it checks whether a is NOT defined, while !!a checks if the variable is defined.

!!a is the same as !(!a). If a is defined, a is true, !a is false, and !!a is true.

@Warren Davis 2014-04-24 13:05:49

Tons of great answers here, but if you've read down this far, this helped me to 'get it'. Open the console on Chrome (etc), and start typing:

!(!(1))
!(!(0))
!(!('truthy')) 
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc, etc, until the light goes on ;)

Naturally, these are all the same as merely typing !!someThing, but the added parentheses might help make it more understandable.

@Benny 2013-02-22 23:45:27

Brew some tea:

!! is not an operator. It is the double-use of ! -- which is the logical "not" operator.


In theory:

! determines the "truth" of what a value is not:

  • The truth is that false is not true (that's why !false results in true)

  • The truth is that true is not false (that's why !true results in false)


!! determines the "truth" of what a value is not not:

  • The truth is that true is not not true (that's why !!true results in true)

  • The truth is that false is not not false (that's why !!false results in false)


What we wish to determine in the comparison is the "truth" about the value of a reference, not the value of the reference itself. There is a use-case where we might want to know the truth about a value, even if we expect the value to be false (or falsey), or if we expect the value not to be typeof boolean.


In practice:

Consider a concise function which detects feature functionality (and in this case, platform compatibility) by way of dynamic typing (aka "duck typing"). We want to write a function that returns true if a user's browser supports the HTML5 <audio> element, but we don't want the function to throw an error if <audio> is undefined; and we don't want to use try ... catch to handle any possible errors (because they're gross); and also we don't want to use a check inside the function that won't consistently reveal the truth about the feature (for example, document.createElement('audio') will still create an element called <audio> even if HTML5 <audio> is not supported).


Here are the three approaches:

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

Each function accepts an argument for a <tag> and an attribute to look for, but they each return different values based on what the comparisons determine.

But wait, there's more!

Some of you probably noticed that in this specific example, one could simply check for a property using the slightly more performant means of checking if the object in question has a property. There are two ways to do this:

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

We digress...

However rare these situations may be, there may exist a few scenarios where the most concise, most performant, and thus most preferred means of getting true from a non-boolean, possibly undefined value is indeed by using !!. Hopefully this ridiculously clears it up.

@Tom Auger 2016-04-06 13:27:19

totally awesome answer, but I fail to see the utility of the !! construct. Since an if() statement already casts the expression to boolean, explicitly casting the return value of a testing function to boolean is redundant - since "truthiness" === true as far as an if() statement goes anyway. Or am I missing a scenario where you NEED a truthy expression to actually be boolean true?

@Benny 2018-05-31 15:41:36

@TomAuger if() statements do cast boolean against falsey values, but say you want to actually set a boolean flag on an object - it won't cast it like an if() statement does. For example object.hasTheThing = !!castTheReturnValToBoolNoMatterWhat() would set either true or false instead of the real return value. Another example is maybe all admins are id of 0 and non-admins are id 1 or higher. To get true if someone is not an admin you could do person.isNotAdmin = !!admin.id. Few use cases, but it's concise when there is.

@rob_james 2012-04-24 12:22:05

This is a really handy way to check for undefined, "undefined", null, "null", ""

if (!!var1 && !!var2 && !!var3 && !!var4 ){
   //... some code here
}

@rob_james 2012-10-28 17:22:37

Why? I still need to know var1 through 4 have values in them.

@nalply 2012-10-29 07:31:33

Because the && operators already "convert" its operators to boolean.

@rob_james 2012-10-29 21:25:10

huh - cool! Cheers. For the record, I was trying to indicate that it was good to check a lot of values. Can you imagine doing that without boolean conversion?! Mental! Anyway, that is good to know. Does the same happen with || ?

@nalply 2012-10-30 09:16:04

I have to take back my comment. I was wrong. It's not the && operators, but the if statement which "converts". Perhaps a good StackOverflow question?

@aikeru 2013-08-21 21:18:59

I think it is the && operator, as if you remove the surrounding if, you still get all the same behavior of the expression, which if is just testing the result of...

@John Montgomery 2017-09-11 18:39:10

For the record, it's definitely the if that converts - && returns either the first falsy value or the last value. For instance, with var a = b && c && d, a will be equal to b (the actual value of b, not true or false) if b is falsy, c if b is truthy and c is falsy, or d if both b and c are truthy (regardless of d's truthiness).

@Steve Harrison 2009-04-24 08:20:19

It seems that the !! operator results in a double negation.

var foo = "Hello World!";

!foo // Result: false
!!foo // Result: true

@Tom Ritter 2009-09-10 17:28:36

It's a horribly obscure way to do a type conversion.

! is NOT. So !true is false, and !false is true. !0 is true, and !1 is false.

So you're converting a value to a boolean, then inverting it, then inverting it again.

// Maximum Obscurity:
val.enabled = !!userId;

// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;

// And finally, much easier to understand:
val.enabled = (userId != 0);

@cllpse 2009-09-10 17:38:29

!!false = false. !!true = true

@Andy Gaskell 2009-09-10 17:43:22

(userId == 0) ? false : true; hurts my brain the least.

@Imagist 2009-09-10 19:02:33

Yeah, I agree with Andy; using the ternary operator seems to be the clearest way. If it works (I'm not sure it does) then var.enabled = (bool) userId; seems pretty clear to me also.

@Luis Abreu 2009-09-14 12:10:19

How about using === and !=== instead of ==/!=

@Mariano Desanze 2010-04-23 13:40:01

@Luis Abreu: the === or !=== will not work here, becase they compare the exact result without converting anything. Then if the userId is false and you use userId !== 0 then the result will be true which is wrong.

@Ben Regenspan 2010-10-13 16:26:22

Is the "much easier to understand" variant really much easier to understand here? The check against 0 is not an actual check against 0, but a check against the somewhat weird list of values Javascript considers equal to 0. userId ? true : false makes more clear that there is conversion going on and handles the case where userId's value might have been explicitly set to undefined

@adamJLev 2010-10-24 23:36:07

My brain doesn't have any problem decoding !!var into Boolean(var) .. and !! is faster (less instructions to process) and shorter than the alternatives.

@Malvolio 2011-10-18 07:19:57

How is this any more obscure than, for example, the single-bang operator?

@Ricky Clarkson 2012-05-07 14:14:28

What do the () around userId != 0 add in the final example?

@Dave Rager 2012-05-18 19:29:12

@RickyClarkson mainly it's for readability since syntactically it's not required. Some use the convention of always wrapping a conditional in parenthesis to set it apart from the rest of the expression.

@Ricky Clarkson 2012-05-18 23:32:50

Fair enough. I find it takes me longer to read because it's unnecessary and unusual.

@Triqui 2012-12-13 14:06:58

I like this: config[!!loadData === loadData? "autoLoad" : "data"] = loadData;

@Camilo Martin 2012-12-18 08:04:06

Worth noting that some minifiers (such as Google's Closure Compiler) turn true into !0 and false into !1 to save characters (note that the order looks awkward but is correct, !0 === true && !1 === false).

@Rob 2013-02-14 01:41:47

Evidently this obscurity is well worth it as it handles null very nicely. if (!!value) alert('value is not null') else alert('value is null') This behavior is what got me interested in looking up what in the world it was doing.

@Rob 2013-02-14 01:55:05

In addition to what I commented above, here is how I had to check for the null-ish type states a string could be in before to have a ifNullOrDefault(value, defaultValue) type function for strings. (valueString === null || valueString === undefined || valueString === ""). I don't care how obscure !! is much easier to read. If people don't know it, they will look it up.

@voltrevo 2014-01-10 13:22:10

x != 0 does not produce false for the falsy values undefined and NaN.

@Phil H 2014-02-12 09:48:44

For reference, Boolean(x) is as fast as !! on current browsers (jsperf.com/boolean-conversion-speed). And also a == b ? true : false is just the same as (a==b): the result is already boolean.

@philh 2014-09-30 08:50:49

I disagree with this. userId != 0 is true for null, NaN and undefined, but false for false. If you want exactly that behaviour, you probably should be explicit about it. But even if it worked exactly the same as !!userId, it's not clear whether you want those values to come up false here, or whether you just failed to consider Javascript's type conversion rules.

@dave 2014-12-15 20:22:16

You picked a specific case where !! is obscure, but in some cases checking for != 0 is no better. For example, when working with bitfields exceeding 8 bits in Objective-C, (BOOL)(512 & 512) evaluates to NO because the casted BOOL only evaluates the lowest 8 bits of the result. When evaluating bit fields, (bit & expectedBit) != 0 is equally as obscure as !!(bit & expectedBit), and !! saves a few keystrokes. Both solutions are equally viable, and neither are horrible by any stretch.

@RiaD 2015-02-23 17:50:43

Note, that those codes are not completely equivalent.For x= NaN !!x = False, and x != 0 is True

@SidOfc 2015-05-13 13:24:51

I think method #3 is much more obscure than the second imho, the second explains what values it can be at the cost of extra code whereas the third doesnt.. just my observation tho ;)

@Oriol 2016-01-29 03:20:14

if you want a non-obscure conversion to boolean, use Boolean(x). x != 0 is unreliable in lots of cases.

@Reinstate Monica --Brondahl-- 2016-12-21 12:28:34

"Horribly obscure" ... "very common idiomatic javascript usage" See also the various comments pointing out the flaws with x != 0

@coderade 2017-02-14 17:18:29

The !! operator is on the Airbnb JS Style guide github.com/airbnb/javascript/tree/es5-deprecated/… So I think that your use is a good idea.

@Sava B. 2018-08-14 20:37:13

It's not that obscure, I've seen it and heard about its use often enough, in js as well as c++. Maybe a bit unclear if you aren't aware of it.

@eduardomoroni 2018-11-29 12:55:54

If you're trying to corce why don't val.enabled = (userId != false);

@mFeinstein 2019-03-20 19:45:59

What's the point of this code then: if(!!idTokenResult.claims.admin) wouldn't it be the same without the !!? Found this at a Firebase Auth doc.

@Kumar Sidharth 2019-08-22 11:50:45

(userId === 0 && userId !== null && userId !== undefined) ? false : true; This is much more painfull. @AndyGaskell . Such are the scenarios where not not feels helpful.

@Prakash 2011-03-23 11:53:45

It simulates the behavior of the Boolean() casting function. The first NOT returns a Boolean value no matter what operand it is given. The second NOT negates that Boolean value and so gives the true Boolean value of a variable. The end result is the same as using the Boolean() function on a value.

@Sergey Ilinsky 2010-12-02 20:21:14

Double boolean negation. Often used to check if value is not undefined.

@Paul McMillan 2009-09-10 17:27:47

It converts the suffix to a Boolean value.

@Justin Johnson 2009-09-10 21:19:09

It's not a single operator, it's two. It's equivalent to the following and is a quick way to cast a value to boolean.

val.enabled = !(!enable);

Related Questions

Sponsored Content

89 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6162130 View
  • 7684 Score
  • 89 Answer
  • Tags:   javascript arrays

86 Answered Questions

[SOLVED] How do JavaScript closures work?

23 Answered Questions

[SOLVED] Does Python have a ternary conditional operator?

18 Answered Questions

[SOLVED] Reference — What does this symbol mean in PHP?

23 Answered Questions

[SOLVED] What is the "-->" operator in C++?

27 Answered Questions

[SOLVED] What does "use strict" do in JavaScript, and what is the reasoning behind it?

69 Answered Questions

[SOLVED] What is the most efficient way to deep clone an object in JavaScript?

3 Answered Questions

4 Answered Questions

[SOLVED] What does the C ??!??! operator do?

  • 2011-10-19 16:56:59
  • Peter Olson
  • 252151 View
  • 1918 Score
  • 4 Answer
  • Tags:   c operators trigraphs

Sponsored Content