220

Possible Duplicate:
What is the !! (not not) operator in JavaScript?
What does the !! operator (double exclamation point) mean in JavaScript?

So I was debuging some code and ran across this:

var foo.bar = 0; // this is actually passed from another function, adding it for context

function(foo) {
    var someVar = !!foo.bar;

    if (foo.bar) {
      // ..stuff happens
    } else {
      // .. something else happens
    }
}

Okay my questions is what is the point of !!? All that is doing is making the 0 === false.

  1. Is there any benefit to using that compared to boolean(foo.bar)?

  2. foo.bar can be evaluated in an if as is because 0 === false already, so why go through the conversion? (someVar is not reused anywhere else)

nck
  • 41
  • 3
  • 7
jpalladino84
  • 2,480
  • 2
  • 15
  • 16

3 Answers3

340

This converts a value to a boolean and ensures a boolean type.

"foo"      // Evaluates to "foo".
!"foo"     // Evaluates to false.
!!"foo"    // Evaluates to true.

If foo.bar is passed through, then it may not be 0 but some other falsy value. See the following truth table:

Truth Table for javascript

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

Source: Doug Crockford

Javascript also gets really weird when it comes to NaN values. And this is the only case I can think of off the top of my head where !! would behave differently to ===.

NaN   ===  NaN     //false
!!NaN === !!NaN    //true

// !!NaN is false
RayLoveless
  • 19,880
  • 21
  • 76
  • 94
Gazler
  • 83,029
  • 18
  • 279
  • 245
  • 16
    That doesn't actually answer the question. The question asks: "foo.bar can be evaluated in an if as is because 0 === false already, so why go through the conversion?" Your answer explains *that* it ensures a Boolean type, but the OP already knew that; the question is, what's the *point* of ensuring a Boolean type? – ruakh Feb 14 '12 at 21:52
  • 1
    @ruakh The if statement is implicit and will not use === – Gazler Feb 14 '12 at 21:54
  • 1
    Sorry, could you elaborate your last comment a bit? Because I really don't see what point it was trying to make. :-/ – ruakh Feb 14 '12 at 22:04
  • @ruakh I can see how that wouldn't make sense. I was trying to relate to the code OP posted `if foo.bar` however the only reason apart from preference I can speculate is when dealing with NaN. I have editted this into my answer. – Gazler Feb 14 '12 at 22:25
  • @makhdumi: `==` always results in either `true` or `false`, so that longer expression is redundant: `x == true` is exactly the same result as `x == true ? true : false`. – ToolmakerSteve Oct 27 '20 at 19:47
19

I think the answer is that there isn't really much point. We can speculate about how it came about:

  • maybe an earlier version of the function used someVar in multiple places, or in ways that genuinely benefited from having true or false, so this made more sense.
  • maybe the person who wrote the function is so used to using !! to convert to true/false that (s)he didn't even notice that it wasn't necessary here.
  • maybe the person who wrote the function feels that every computation (in this case, Boolean conversion) should be given a meaningful name by assigning some variable to its result.
  • maybe, since Boolean conversion in JavaScript is surprisingly error-prone (in that e.g. new Boolean(false) is a true-valued value), the person who wrote the function feels that it should always be done explicitly rather than implicitly — even though the effect is the same — just to call attention to it as a potential point of error.
    • this, of course, presupposes that the person who wrote the function thinks of !! as an "explicit" Boolean conversion. Technically it's not — it uses the same implicit Boolean conversion that if does — but if you're used to this idiom, then it amounts to an explicit conversion.

but in my subjective opinion, none of those reasons is a very good one!

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • 2
    This is especially relevant, and makes me prefer this answer; "(in that e.g. new Boolean(false) is a true-valued value)," – Nate Anderson Jan 18 '17 at 05:30
  • 1
    I think this is better than the accepted answer as it actually explains WHY the double exclamation mark may have been used as the OP asked, rather than just explaining what it does. I think it would be helpful to state that !! gives you a boolean value whereas new Boolean() gives you a boolean object. – Caltor Feb 27 '19 at 10:43
  • `(new Boolean(false)) == false` in chrome 73... – Ulysse BN Apr 29 '19 at 13:59
  • 1
    This may not have been properly documented at the time of the OP, however `(new Boolean(false)) == false` while `(new Boolean(false)) !== false` because `new Boolean(false)` creates an object. As stated in Mozilla's docs, if you want to convert to a boolean value, you must use `Boolean(expression)` instead. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean – AlexAngc Jan 14 '20 at 07:59
  • @AngryCub: I'm not sure why you and Ulysse BN bring up `== false`. My point was simply that `new Boolean(false)` is truthy, as you'll see if you use it as the condition of an `if` or `while` or the like. – ruakh Jan 14 '20 at 08:34
  • @ruakh yes, your point was correct, but I was attempting to disambiguate something that initially confused me *(and apparently Ulysse BN as well)*, considering the OP was specifically asking about `Boolean(exp)`, as opposed to `new Boolean(exp)`. In other words, to answer the first part of their question, `!!exp` is seemingly the same than `Boolean(exp)`. – AlexAngc Jan 14 '20 at 09:06
  • 1
    @AngryCub: Re: "the OP was specifically asking about `Boolean(exp)`": Oh! I don't think I even noticed that line. (Mea culpa. Looking at the edit history, I see that it was much less prominently formatted back then, but still.) My mention of `new Boolean(false)` was intended only as an example of how counterintuitive the JavaScript boolean-conversion rules can be; it's just a coincidence that it was somewhat similar to something else the OP was asking about. – ruakh Jan 15 '20 at 07:17
7

As stated above, it forces an object with a boolean type. You can see for yourself:

    (function typecheck() {
      var a = "a";
      var b = !a;
      var c = !!a;
    
      console.log("var a =", a, typeof(a))
      console.log("var b =", b, typeof(b))
      console.log("var c =", c, typeof(c))
    })();

If you are simply doing comparisons, the conversion merely saves you a type coercion later on.

FYI, the following values are coerced to FALSE in JavaScript:

  • false
  • 0
  • ""
  • null
  • undefined
Inigo
  • 12,186
  • 5
  • 41
  • 70
Matt Brock
  • 5,337
  • 1
  • 27
  • 26
  • By 'coerced to FALSE' do you mean if I do: something like `var b = (nullthing) ? 'sad' : 'happy'` I can reliably get b = 'happy' if nullthing is 0, null, undefined blank or false? I could have sworn I've had issues where it complained that it was undefined or null in these types of situations. – Z2VvZ3Vp Apr 15 '15 at 00:18
  • The comparison rules are a little strange. [Here is a good in-depth explanation](http://www.sitepoint.com/javascript-truthy-falsy/). In the example you give, you are correct that you'll get a reference error. – Matt Brock Apr 15 '15 at 00:57