Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

+!! operator in an if statement

Tags:

javascript

I was reviewing the code for an angularjs factory to better understand how it works. The code contains an if statement that I don't fully understand.

In a plnkr demo the author wrote this:

if ((+!!config.template) + (+!!config.templateUrl) !== 1) {   throw new Error('Expected modal to have exactly one of either `template` or `templateUrl`'); } 

It is slightly different in the github repo:

if (!(!config.template ^ !config.templateUrl)) {   throw new Error('Expected modal to have exactly one of either `template` or `templateUrl`'); } 

Obviously by the error message it is checking to see if one of the two exists. I'm just not sure how it comes to the conclusion. I have not been able to find any information on ^ or +!

My question is: How does this if statement work? (^ or +! or +!! specifically)

like image 673
Jack Avatar asked Dec 28 '15 22:12

Jack


People also ask

How do you use an or operator in an if statement?

When you combine each one of them with an IF statement, they read like this: AND – =IF(AND(Something is True, Something else is True), Value if True, Value if False) OR – =IF(OR(Something is True, Something else is True), Value if True, Value if False) NOT – =IF(NOT(Something is True), Value if True, Value if False)

Can you use && in an if statement?

In the logical AND ( && ) operator, if both conditions are true , then the if block will be executed. If one or both of the conditions are false , then the else block will be executed.

Which operator means or in if statement?

With the operator “OR,” if one of the conditions is met/True, the program will execute the true_code. If both conditions are false, the program will execute the false_code. It means that OR only returns TRUE if at least one of the conditions is met.


2 Answers

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

like image 168
Matt Ball Avatar answered Sep 19 '22 08:09

Matt Ball


+!! 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) 
like image 44
Travis J Avatar answered Sep 18 '22 08:09

Travis J