37

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.

4

2 Answers 2

44

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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".
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.
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: codepen.io/lucask42/full/GGbqdv
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.

1 Comment

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.