Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use double exclamation marks in an if statement?

I have recently read some code that uses !! to convert a variable to boolean for evaluation in an if statement. This seems somewhat redundant to me as the variable would be evaluated for its boolean value anyway. Are there any performance benefits to doing this or is it for better browser support?

Sample Code:

var x = 0;
var atTop = x===window.scrollY;
if(!!atTop){
   alert("At the top of the page.");
}

Edit:

I have also seen this for operands that are not of boolean types, but I had always assumed that using if would evaluate the boolean value of the variable anyway as all values in Javascript are either "truthy" or "falsey".

Sample Code:

var x = 1;//or any other value including null, undefined, some string, etc
if(!!x){//x is "truthy"
   //wouldn't using if(x) be the same???
   console.log("something...");
}
like image 893
Zamboni Avatar asked Sep 07 '18 22:09

Zamboni


2 Answers

Short answer: No, there is no reason.

In your code, it's already a boolean type, there is no need to convert it, and convert back again, you will always get the same result. Actually, if you have any boolean (true or false), when you use !! with any of them, it will be converted back to it's initial value:

console.log(!!true); // Will be always "true"
console.log(typeof !!true); // It stills a "boolean" type
console.log(!!false); // Will be always "false"
console.log(typeof !!false); // It stills a "boolean" type

Answer for edited question: Yes, it's the same. That's what if(...) actually does - it's trying to convert any type to boolean.

Here is a small test, you can play around with that and add whatever you want inside initialArr array to test, does it behave the same with if and !!:

const initialArr = [
  undefined,
  null,
  true,
  false,
  0,
  3,
  -1,
  +Infinity,
  -Infinity,
  Infinity,
  'any',
  '',
  function() { return 1 },
  {},
  { prop: 1 },
  [],
  [0],
  [0, 1]
];

function testIsTheSame(arr) {
  equolityCounter = 0;
  arr.forEach(item => {
    let ifStatement = false;
    let doubleNotStatement = !!item;
    if(item) {
      ifStatement = true;
    }

    if(ifStatement === doubleNotStatement && typeof ifStatement === typeof doubleNotStatement) {
      equolityCounter++;
    }
  });
  console.log(`Is the same: ${equolityCounter === arr.length}`);
}

testIsTheSame(initialArr);
like image 75
Commercial Suicide Avatar answered Oct 04 '22 04:10

Commercial Suicide


There isn't any run-time benefit (or an objective one) whatsoever to doing this in an if statement. The evaluation performed by the if statement will yield precisely the same result as the evaluation produced by double exclamation mark. There is no difference.

Double exclamation marks is a useful expression to ensure boolean value based on truthyness. Consider, for instance:

var text = undefined;
console.log(text); // undefined
console.log(!!text); // false

// It would make sense here, because a boolean value is expected.
var isTextDefined = !!text;

// It would also affect serialization
JSON.stringify(text); // undefined (non-string)
JSON.stringify(!!text); // "false"

I suppose that this is a habit that was picked up because of the above use cases, thus always converting to boolean when wishing to address a variable's truthyness. It's easier for us (humans and programmers) to follow a rule when it's always applied. You'll either use the blinkers in your car all the time, even when there's nobody around, or it's likely that you'll occasionally (or maybe often) forget to signal when you should have.

like image 36
Ben Barkay Avatar answered Oct 04 '22 03:10

Ben Barkay