4093

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;
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Hexagon Theory
  • 43,627
  • 5
  • 26
  • 30
  • 1389
    Remember it by "bang, bang you're boolean" – Gus Feb 15 '12 at 18:35
  • 123
    Just for the record, don't do what is quoted there. Do `if(vertical !== undefined) this.vertical = Boolean(vertical);` - it is much cleaner and clearer what is going on, requires no unnecessary assignment, is entirely standard, and is just as fast (on current FF and Chrome) http://jsperf.com/boolean-conversion-speed . – Phil H Feb 12 '14 at 09:43
  • "any decent programmer should know what's going on..." - it sometimes helps the compiler generate better code in compiled languages. I know it used to be recommended by Microsoft when using C code because it generated the best code. (It probably still is recommended, but I can't find the reference at the moment). – jww Apr 01 '14 at 12:11
  • 119
    !! is not an operator. It's just the ! operator twice. – Vivek Jul 16 '14 at 07:21
  • 79
    @schabluk, for the record, [order of operations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) is the reason `!!5/0` produces `Infinity` rather than `true`, as produced by `Boolean(5/0)`. `!!5/0` is equivalent to `(!!5)/0` -- a.k.a `true/0` -- due to the `!` operator having a higher precedence than the `/` operator. If you wanted to Booleanize `5/0` using a double-bang, you'd need to use `!!(5/0)`. – matty May 24 '15 at 13:47
  • Put simply: !!vertical gives you a boolean value as to whether 'vertical' is defined or non-false. – user2808054 Oct 13 '15 at 09:23
  • 2
    [What does !!(x) mean in C (esp. the Linux kernel)?](http://stackoverflow.com/q/2527086/995714) – phuclv Apr 29 '17 at 09:40
  • 2
    Simplely explain: `!!value === Boolean(value)` – Shuai Li Dec 14 '18 at 07:16
  • 41
    @Gus Just so you know, I read your comment waaaay back in 2012. Over the course of the 7 years since then, I've always said humorously in my mind "Bang bang! you're boolean!" when inverting a boolean, and I've always remembered how as a result. I decided to look up your comment today and let you know :-) – Zachary Schuessler Jul 19 '19 at 17:39
  • 9
    @ZacharySchuessler thx, I'm pleased so many like it, and I've even seen it quoted (and credited) in tutorial sites and such now which is awesome :) never dreamed I'd be coining such a popular mnemonic. – Gus Aug 28 '19 at 14:10
  • I like to think of it as an "is truthy" check. – BillMux Dec 10 '21 at 11:14
  • it will just force the variable to have a boolean value. Its useful for assertions and checks. – Jone Polvora Mar 26 '22 at 19:02
  • !!!!!!!!!!!!!!!!!!false === false – Aidin53 Jul 06 '22 at 05:05
  • unique code `true + 1 = 2` .brr – perona chan May 17 '23 at 14:54

42 Answers42

3651

It converts Object to boolean. If it was falsy (e.g., 0, null, undefined, etc.), it would be false, otherwise, true.

!object  // Inverted Boolean
!!object // Noninverted Boolean, so true Boolean representation

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

It may be simpler to do:

Boolean(object) // Boolean

Real World Example "Test IE version":

const 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
Matt Morgan
  • 4,900
  • 4
  • 21
  • 30
stevehipwell
  • 56,138
  • 6
  • 44
  • 61
  • 163
    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). – Chuck Apr 24 '09 at 17:14
  • 154
    An easy way to describe it is: Boolean(5) === !!5; Same casting, fewer characters. – Micah Snyder Apr 24 '09 at 18:27
  • 59
    This is used to convert truthy values to boolean true, and falsy values too boolean false. – thetoolman Jul 16 '12 at 03:53
  • 17
    @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: http://jsfiddle.net/eekbu/ – victorvartan Feb 03 '13 at 12:24
  • 9
    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. – rds Mar 26 '14 at 19:43
  • 1
    Why would anyone need to use this? I'm trying to think of a use case. – sparkyShorts Dec 05 '16 at 18:26
  • 6
    @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. – geofflee Mar 02 '17 at 00:33
  • 2
    @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() };` – Dale Harris Mar 20 '18 at 17:15
  • 1
    Is it a good practice to negate !!! (3 times) an object to get the boolean value? – Diego Ponciano Sep 08 '21 at 23:09
  • 1
    @DiegoPonciano No, `!!!value` would negate `!!value`, which in the end is the same as `!value`. – Abel Nov 17 '21 at 07:00
  • 4
    @victorvartan Your [jsfiddle](http://jsfiddle.net/eekbu/) uses `new Boolean(5)`, but if you change it to just use `Boolean(5)` then your code returns true for both variables – icc97 Mar 04 '22 at 10:11
1018

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

! means 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, inverting it, and 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);

    // Or just
    val.enabled = Boolean(userId);

Note: the middle two expressions aren't exactly equivalent to the first expression when it comes to some edge cases (when userId is [], for example) due to the way the != operator works and what values are considered truthy.

Dmitriy Popov
  • 2,150
  • 3
  • 25
  • 34
Tom Ritter
  • 99,986
  • 30
  • 138
  • 174
  • 110
    !!false = false. !!true = true – cllpse Sep 10 '09 at 17:38
  • 135
    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` – Ben Regenspan Oct 13 '10 at 16:26
  • 83
    My brain doesn't have any problem decoding `!!var` into `Boolean(var)` .. and `!!` is faster (less instructions to process) and shorter than the alternatives. – adamJLev Oct 24 '10 at 23:36
  • 10
    `!!false` is false. `false != 0` is true. So they're not equivalent. `!!` serves the useful purpose of coercing *anything* to a boolean. – slim Aug 21 '20 at 16:19
  • 22
    I realize you wrote this answer many years ago, but in the interest of refining it for today: The easiest to understand is to **say what you mean**: `Boolean(x)`. I don't consider any of your alternatives easy to understand. Worse, there is at least one case where using equality operator `x != 0` gives a different result than `Boolean(x)` or `!!x`: try `[]` for x. Also, if you do like using equality operator, to get its "truthiness" rules, why wouldn't you do the more obvious `(userId == true)` instead of `(userId != 0)`? – ToolmakerSteve Oct 27 '20 at 20:17
  • 3
    @cllpse You mean !!false === false and !!true === true ? ;-) – Maik Lowrey Apr 08 '21 at 20:33
  • 4
    It's worth noting though that `!!` is portable to virtually any C-style language – Sam Johnson Aug 13 '21 at 06:42
  • 2
    @slim `false != 0` is actually `false`. – Unmitigated Aug 05 '22 at 19:54
583

!!expr (two ! operators followed by an expression) 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
          !!(1/0) === true  // Infinity 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 value is falsy
      !!undefined === false // undefined primitive is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!
Salman A
  • 262,204
  • 82
  • 430
  • 521
214

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.

Benny Schmidt
  • 3,230
  • 1
  • 19
  • 14
  • 7
    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`? – Tom Auger Apr 06 '16 at 13:27
  • 5
    @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. – Benny Schmidt May 31 '18 at 15:41
121

!! converts the value to the right of it to its equivalent Boolean value. (Think poor man's way of "type-casting".) Its intent is usually to convey to the reader that the code does not care what value is in the variable, but what its "truth" value is.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
  • 5
    Or in the case of a boolean value on the right, it does nothing. – Daniel A. White Sep 10 '09 at 17:28
  • 4
    @Daniel: `!` still flips the value to the right. In the case of a boolean the right-most `!` negates the value, while the left-most `!` negates it once again. Net effect is that there is no change, but most engines will generate op codes for the double negation. – Crescent Fresh Sep 10 '09 at 17:34
94

!!foo applies the unary not operator twice and is used to cast to a Boolean type similar to the use of unary plus +foo to cast to a number and concatenating an empty string ''+foo to cast to a string.

Instead of these hacks, you can also use the constructor functions corresponding to the primitive types (without using new) to explicitly cast values, i.e.,

Boolean(foo) === !!foo
Number(foo)  === +foo
String(foo)  === ''+foo
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Christoph
  • 164,997
  • 36
  • 182
  • 240
  • But then you can run into issues with instanceof. new Boolean(1) instanceof Object -> true !!1 instanceof Object -> false – Seamus Oct 07 '10 at 12:53
  • 16
    no, you can't: notice that the constructor functions are called without `new` - as explicitly mentioned in my answer – Christoph Oct 08 '10 at 09:46
  • 2
    fantastic! This is useful for a little hack when you need to evaluate strings with "0" as false instead of true. (i.e. when reading values from selects, because they are read as String). So, if you want to consider "0" as negative (Boolean false), asuming `x="0"` just do: `x=!!+x; //false` which is the same as `Boolean(Number(x))` Number (or +x) converts the string "0" to 0, which DOES evaluate to false, and then Boolean (!!x) casts it to boolean directly. Easy peasy! – DiegoDD Jun 03 '13 at 18:13
  • 2
    @DiegoDD why would you choose `!!+x` vs `x !== "0"`? – placeybordeaux Dec 29 '15 at 23:46
  • @placeybordeaux because for example you may want to convert the value and assign it to other variable, regardless if you are going to compare it to something else or not. – DiegoDD Jan 05 '16 at 18:26
  • I do hope this becomes the accepted answer `Boolean(foo)` is clearer to read for everyone than `!!foo`. Code should be written so that others can read it, not for minor performance gains or for neat tricks. – icc97 Mar 04 '22 at 10:15
93

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.

The only thing 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: site has changed; this is an archived copy) 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, in my opinion, a serious mistake. if (-1) is still the way to go here.

Original Equivalent Result Notes
if (-1 == true) console.log("spam") if (-1 == 1) undefined
if (-1 == false) console.log("spam") if (-1 == 0) undefined
if (true == -1) console.log("spam") if (1 == -1) undefined Order doesn't
matter...
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 truthiness/falsiness?

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

Though even in this case, the !! really is superfluous. One ! was enough to cast to a Boolean, and you're just checking equality.


EDIT 24 Oct 2017, 6 Feb 19:

Third-party libraries that expect explicit Boolean values

Here's an interesting case... !! might be useful when third-party libraries expect explicit Boolean values.

React

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

  • One fix involves the bangbang, which coerces 0 into !!0, which is false: {!!messageCount && <div>You have messages!</div>}

  • JSX' documentation suggests 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}

TypeScript

The 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 (or cast to the proper Boolean another way) 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 and TypeScript conventions, not ones inherent to JavaScript.

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

ruffin
  • 16,507
  • 9
  • 88
  • 138
  • Good explanation. So would you say the !! is not strictly necessary in this [Worker feature detection](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) example? `if (!!window.Worker)` – jk7 May 06 '15 at 20:41
  • 2
    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. – ruffin May 06 '15 at 20:54
67

It's just the logical NOT operator, twice. It's used to convert something to Boolean, e.g.:

true === !!10

false === !!0
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Greg
  • 316,276
  • 54
  • 369
  • 333
35

It converts the suffix to a Boolean value.

Paul McMillan
  • 19,693
  • 9
  • 57
  • 71
32

It's a double not operation. The first ! converts the value to Boolean and inverts its logical value. The second ! inverts the logical value back.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
32

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

var foo = "Hello, World!";

!foo // Result: false
!!foo // Result: true
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Steve Harrison
  • 121,227
  • 16
  • 87
  • 72
31

!! is using the NOT operation twice together. ! converts the value to a Boolean and reverses it, so using it twice, showing the Boolean (false or true) of that value. 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, !! makes us sure the value we get is Boolean, not falsy, truthy, string, etc...

So it's like using the Boolean function in JavaScript, but an easier and shorter way to convert a value to Boolean:

var zero = 0;
!!zero; //false
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alireza
  • 100,211
  • 27
  • 269
  • 172
31

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.

Prakash
  • 6,562
  • 3
  • 25
  • 33
  • When was that Boolean() function introduced? Is it actually a function (not a constructor?)? Can you link to documentation in your answer? (But ***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today.) – Peter Mortensen Aug 05 '22 at 12:04
  • OK, *"[The Boolean() Function](https://www.w3schools.com/js/js_booleans.asp)"*. But that is W3Schools. What is the official documentation? – Peter Mortensen Aug 05 '22 at 14:12
25

! 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 of enable as a Boolean.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Annika Backstrom
  • 13,937
  • 6
  • 46
  • 52
24

I think worth mentioning is that a condition combined with logical AND/OR will not return a Boolean value, but the last success or first fail in case of && and the first success or last fail in case of || of the 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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
GreQ
  • 989
  • 1
  • 8
  • 5
21

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.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Navin Rauniyar
  • 10,127
  • 14
  • 45
  • 68
  • 2
    Very close to the important distinction. **Key is that `0 === false` is false and `!!0 === false` is true.** – ruffin Apr 29 '15 at 17:38
20

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);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Justin Johnson
  • 30,978
  • 7
  • 65
  • 89
19

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);   // -> false
console.log(!0 === false);  // -> false
console.log(!!0 === false); // -> true
Karol S
  • 9,028
  • 2
  • 32
  • 45
Twitter khuong291
  • 11,328
  • 15
  • 80
  • 116
16

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 you would use !!.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Darren Clark
  • 2,983
  • 20
  • 15
15

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.

Damian Yerrick
  • 4,602
  • 2
  • 26
  • 64
15

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 "falsy" 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 falsy value, resulting in an actual Boolean type, and then the second one "inverts" it back again to its 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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
KWallace
  • 624
  • 7
  • 15
12

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 above (b && b.foo) is (b || {}).foo. Those are equivalent, 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
  • 12,559
  • 2
  • 39
  • 34
12

It is double Boolean negation. It is often used to check if a value is not undefined.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sergey Ilinsky
  • 31,255
  • 9
  • 54
  • 56
11

There are tons of great answers here, but if you've read down this far, this helped me to 'get it'. Open the console in 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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Warren Davis
  • 333
  • 3
  • 4
  • Re *"Open the console in Chrome"*: Can you be more specific (instructions)? (But (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today).) – Peter Mortensen Aug 05 '22 at 12:14
11

!!x is shorthand for Boolean(x).

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Greg Gum
  • 33,478
  • 39
  • 162
  • 233
7

After seeing all these great answers, I would like to add another reason for using !!. Currently 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();
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Wouter Vanherck
  • 2,070
  • 3
  • 27
  • 41
6

Here is a piece of code from AngularJS:

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 the 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 assigned undefined then !requestAnimationFrame would be true and one more ! of it would be false.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
6

Use the logical not operator two times.

It means !true = false and !!true = true.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Abhay Dixit
  • 998
  • 8
  • 28
6

It returns the Boolean value of a variable.

Instead, the Boolean class can be used.

(Please read the code descriptions.)

var X = "test"; // The X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value because 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 `!!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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
efkan
  • 12,991
  • 6
  • 73
  • 106
  • 1
    Upvoted.. Was actually gonna answer with this if not here already. Using the Boolean object imo is a better approach from a readability standpoint. For example, there is no "what does Boolean do" SO question with 3k plus upvotes - like this current question. – iPzard Jan 26 '21 at 20:47
6

It is important to remember the evaluations to true and false in JavaScript:

  • Everything with a "Value" is true (namely truthy), for example:

    • 101,
    • 3.1415,
    • -11,
    • "Lucky Brain",
    • new Object()
    • and, of course, true
  • Everything without a "Value" is false (namely falsy), for example:

    • 0,
    • -0,
    • "" (empty string),
    • undefined,
    • null,
    • NaN (not a number)
    • and, of course, false

Applying the "logical not" operator (!) evaluates the operand, converting it to boolean and then negating it. Applying it twice will negate the negation, effectively converting the value to boolean. Not applying the operator will just be a regular assignment of the exact value. Examples:

var value = 23; // number
var valueAsNegatedBoolean = !value; // boolean falsy (because 23 is truthy)
var valueAsBoolean = !!value; // boolean truthy
var copyOfValue = value; // number 23

var value2 = 0;
var value2AsNegatedBoolean = !value2; // boolean truthy (because 0 is falsy)
var value2AsBoolean = !!value2; // boolean falsy
var copyOfValue2 = value2; // number 0
  • value2 = value; assigns the exact object value even if it is not boolean hence value2 won't necessarily end up being boolean.
  • value2 = !!value; assigns a guaranteed boolean as the result of the double negation of the operand value and it is equivalent to the following but much shorter and readable:

if (value) {
  value2 = true;
} else {
  value2 = false;
}
Lucky Brain
  • 1,551
  • 12
  • 14
  • How does this add anything new or useful to the other answers? – Andreas Jan 21 '21 at 17:36
  • 1
    None of the other answers clarifies the concepts of how JavaScript evaluates what is **truthy** or **falsy**. Novice JavaScript developers need to know that the "not not" operator is using implicitly the original loose comparison method instead of the exact `===` or `!==` operators and also the hidden cast operation that is happening behind the scenes and I show it in the example I provide. – Lucky Brain Jan 22 '21 at 01:33
5

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 leads to the following idiom that you can see in your source code:

!!x // Same as Boolean(x). Note double exclamation mark
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
GibboK
  • 71,848
  • 143
  • 435
  • 658
5

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

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

console.log(new Boolean(null).valueOf()); // Not recommended for converting 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 falsy 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 falsy 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 falsy value.
console.log(new Example(vertical).vertical); // The falsy or truthy value of this.vertical which happens to be false either way
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

Falsy values in JavaScript coerce to false, and truthy values coerce to true. Falsy 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 falsy, 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>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mystical
  • 2,505
  • 2
  • 24
  • 43
4

!! is simply the NOT operator twice. The net effect is just converting anything to ensure a Boolean data type. For example.

!!undefined is false
!!0 is false
!!null is false
!!anyobject is true
!!true is true
!!false is false
!0 is true
!1 is false
!!'' is false

Umesh Bhutada
  • 301
  • 2
  • 4
3
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.

3

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 than zero, not empty strings, {}, [] and new Date() so,

!!("test") /* Is true */
!!("") /* Is false */
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lakmal
  • 779
  • 1
  • 8
  • 16
2

This is the simplest answer I've found: It is equivalent to Boolean(value) in how it works.

Abdulsalam
  • 275
  • 4
  • 6
2

You can consider !! in this way:

  1. When the first ! applies, the variable becomes boolean, but with an opposite value
  2. Then, the second ! just recovers a justice and revert value back to its original equivalent
anatol
  • 1,680
  • 2
  • 24
  • 47
1

!! is not an operator. It's just the ! operator twice.

But with JavaScript, apply !! for converting Object to Boolean is redundant and verbose in the most cases because:

Any object of which the value is not undefined or null, including a Boolean object whose value is false, evaluates to true when passed to a conditional statement

Example: if ({}) { console.log("{} is true")} // logs: "{} is true"

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • "...a Boolean object whose value is false, evaluates to true when..." Huh? I mean JavaScript deserves hate for all it's stupidity, but I don't believe it is really that stupid is it? – swpalmer Nov 19 '21 at 15:18
  • @swpalmer https://jsfiddle.net/rsgqb5zp/ watch and be amazed! But less glibly there is a distinction between Boolean (big b) objects which are reference types and boolean (small b) which are value types. The if conditional checks reference types to see if they are not null or undefined. – Tim Seguine Dec 06 '21 at 20:32
0

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 the user has a major or not and we have a function just like:

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

But the answer is not important to us. We just want to check if it has a major or not and we need a Boolean value (true or false). How do 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 returns false, but because the value has exits and we need to return true, we use ! twice to return the correct answer, !(!this.major).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mahdi Abedi
  • 124
  • 2
  • 3
0

const foo = 'bar';
console.log(!!foo); // Boolean: true

! negates (inverts) a value and always returns/ produces a Boolean. So !'bar' would yield false (because 'bar' is truthy => negated + Boolean = false). With the additional ! operator, the value is negated again, so false becomes true.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mile Mijatović
  • 2,948
  • 2
  • 22
  • 41
0

Just to check if exist

if(!!isComplianceOnHold){
//write code here is not undefined
//if isComplianceOnHold is undefined or null will not enter in net is false
// if isComplianceOnHold is not null or even boolean net result is true and enter inside if block
}

Any object of which the value is not undefined or null, including a Boolean object whose value is false, evaluates to true when passed to a conditional statement

Umesh Bhutada
  • 301
  • 2
  • 4
-3

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

if (!!var1 && !!var2 && !!var3 && !!var4 ){
   //... some code here
}
rob_james
  • 1,262
  • 1
  • 12
  • 17
  • Why? I still need to know var1 through 4 have values in them. – rob_james Oct 28 '12 at 17:22
  • 8
    Because the `&&` operators already "convert" its operators to boolean. – nalply Oct 29 '12 at 07:31
  • 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 `||` ? – rob_james Oct 29 '12 at 21:25
  • 7
    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? – nalply Oct 30 '12 at 09:16
  • 3
    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... – aikeru Aug 21 '13 at 21:18
  • 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). – John Montgomery Sep 11 '17 at 18:39