+!! operator in an if statement

Meanwhile, ^ is the bitwise XOR operator.

When dealing with numbers smaller than 2, ^ will work like a boolean OR (||) if you consider 0 = false and 1 = true.


+!! uses implicit conversion to cast a value as a 0 or 1 depending on its boolean value

For the most part, this is to check for existence. For example, an empty string is false (!!"" === false), and so is undefined, and a number of others. Those are the main two though

"Falsey" conversions

+!!""        ===   0
+!!false     ===   0
+!!0         ===   0
+!!undefined ===   0
+!!null      ===   0
+!!NaN       ===   0

"Truthy" conversions

+!!1         ===   1
+!!true      ===   1
+!!"Foo"     ===   1
+!!3.14      ===   1
+!![]        ===   1
+!!{}        ===   1

if ((+!!config.template) + (+!!config.templateUrl) !== 1)

Hopefully this is making more sense at this point. The object config has two properties we are examining. .template and .templateUrl. The implicit cast to a 0 or 1 using +!! is going to be added and then compared to ensure that it is not 1 (which means it is either 0 or 2) - the properties can either both be on or off but not different.

The truth table here is as follows:

template    templateUrl    (+!!) + (+!!)     !==1
"foo"       "foo"              1 + 1         true
undefined   undefined          0 + 0         true
undefined   ""                 0 + 0         true
""          undefined          0 + 0         true
12          ""                 1 + 0         false
""          12                 0 + 1         false
undefined   "foo"              0 + 1         false
""          "foo"              0 + 1         false
"foo"       ""                 1 + 0         false
"foo"       undefined          1 + 0         false

A much simpler method to all of this would have been to just use the implicit boolean conversion

if (!config.template === !config.templateUrl)

This is a horribly unreadable way to write out the boolean value of a variable, and then convert it using unary conversion to give a 0/1 number result.

Consider:

+!!true; //this converts true to false, then to true again, and true is 1 when converted
+!!0; //converts 0 (falsy) to true, then false, and then the numeric 0

Technically speaking !! is not its own operator, it's just the NOT (!) operator twice.

Unary conversion: ECMA spec doc a unary plus attempts to convert to an integer. Number() would also be a valid conversion.


!! converts a value to a boolean (true or false). + then converts that boolean to a number, either 1 for true or 0 for false.

> +true
1
> +false
0

Personally I find it clearer to write something like this, when dealing with two booleans:

if (!config.template == !config.templateUrl) {
  throw ...
}

Code clarity and readability be damned, apparently.

Tags:

Javascript