36

I understand what the double not operator does in JavaScript. I'm curious about it's use though and whether or not a recent assertion that I made is correct.

I said that if (!!someVar) is never meaningful nor is (!!someVar && ... because both the if and the && will cause someVar to be evaluated as a boolean so the !! is superfluous.

In fact, the only time that I could think of that it would be legitimate to use the double not operator is if you wanted to do a strict comparison to another boolean value (so maybe in return value that expects true or false explicitly).

Is this correct? I started to doubt myself when I noticed jQuery 1.3.2 used both if (!!someVar) and return !!someVar && ...

Does the double not have any actual effect in these situations?

My personal opinion is that it just leads to confusion. If I see an if statement, I know it's evaluating it as a boolean.

Community
  • 1
  • 1
Keith Bentrup
  • 11,834
  • 7
  • 49
  • 56
  • 2
    Note that (as Justin points out in his answer to the question you reference http://stackoverflow.com/questions/1406604/what-does-the-operator-double-exclamation-point-mean-in-javascript/1407785#1407785), there is no double-not operator. `!!` merely applies the not operator twice. – outis Feb 01 '10 at 04:31
  • 1
    This 'operator' is the very definition of idiomatic... Unless you know what it is, you're likely to be confused or simply misread this as a single 'not'. I'm going to start using it just to confuse my co-workers :D If anybody's interested, I saw this in the 'wild' in jQuery.grep – Sprague Nov 28 '13 at 16:50
  • 1
    related: [What is the difference between if(!!condition) and if(condition)](http://stackoverflow.com/q/19818574/1048572) – Bergi Jul 19 '14 at 17:45
  • see also [Why use `if (!!err)`?](https://stackoverflow.com/q/27257803/1048572) and [Why use `!!` to coerce a variable to boolean for use in a conditional expression?](https://stackoverflow.com/q/18648179/1048572) – Bergi Aug 04 '17 at 06:50

2 Answers2

43

In the context of if statements I'm with you, it is completely safe because internally, the ToBoolean operation will be executed on the condition expression (see Step 3 on the spec).

But if you want to, lets say, return a boolean value from a function, you should ensure that the result will be actually boolean, for example:

function isFoo () {
  return 0 && true;
}

console.log(isFoo()); // will show zero
typeof isFoo() == "number";

In conclusion, the Boolean Logical Operators can return an operand, and not a Boolean result necessarily:

The Logical AND operator (&&), will return the value of the second operand if the first is truly:

true && "foo"; // "foo"

And it will return the value of the first operand if it is by itself falsy:

NaN && "anything"; // NaN
0 && "anything"; // 0

On the other hand, the Logical OR operator (||) will return the value of the second operand, if the first one is falsy:

false || "bar"; // "bar"

And it will return the value of the first operand if it is by itself non-falsy:

"foo" || "anything"; // "foo"

Maybe it's worth mentioning that the falsy values are: null, undefined, NaN, 0, zero-length string, and of course false.

Anything else (that is not falsy, a Boolean object or a Boolean value), evaluated in boolean context, will return true.

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • Another way of saying this: the logical AND operator returns the first "falsy" operand encountered, while the logical OR operator returns the first "truthy" operand. Also, for the sake of completeness, -0 is also considered "falsy". – TMcManemy Aug 10 '14 at 20:16
  • If you are in a situation where you need to `!!expr` something, consider writing it `Boolean(expr)` instead for the sake of readability, as it is functionally equivalent. – conny Nov 10 '17 at 07:13
  • Here's a use case I encounter regularly: short-circuit rendering in JSX. You can end up rendering a '0' if you try to render a the elements of a zero-length array. I made a codepen to demonstrate: https://codepen.io/lucask42/full/GGbqdv/ – Lucas Kellner Jul 06 '18 at 18:22
0

Yes, !!var is used when you want 0||1 return value.

One is simple comparison of bool values, when you want "a == b" be equivalent of "a xor not b" except a=5 and b=7 would both be true but not be equal.

Another is when you want to coerce a set of conditions into bits of a variable:

 var BIT_NONEMPTY=1;
 var BIT_HASERRORS=2;
 var BIT_HASCHILDREN=4;
 var BIT_HASCONTENT=8;

 result_bitfields = 
    (!!countLines())*BIT_NOTEMPTY +
    (!!errorCode())*BIT_HASERRORS +
    (!!firstChild())*BIT_HASCHILDREN +
    (!!getContent())*BIT_HASCONTENT;

Not very useful in Javascript which lives pretty far from bit values, but may be useful at times.

SF.
  • 13,549
  • 14
  • 71
  • 107
  • 3
    No: !! converts to false or true, not 0 or 1. (In your bitfield example, true is then coerced to 1 and false to 0 by the * operator). – Doin Feb 07 '15 at 14:12