S. W.
S. W.

Reputation: 13

If !0 is truthy then how come "true && !0" returns true and not !0?

From what I understand if both values are truthy it should return the last truthy value which in this case should be !0.

Upvotes: 1

Views: 246

Answers (2)

wiesion
wiesion

Reputation: 2435

While the answer of Droppy is correct, it lacks a proper in-depth explanation of the encountered behavior:

!{statement} is in human readable form simply not {statement}.

! is the logical NOT operator, it reverses the truthiness or falsiness of {statement}.

0 in this case is not converted to anything - it is just a falsy value and since ! is an operator, it returns the result of the inverted falsy/truthy match. From the docs:

Returns false if its single operand can be converted to true; otherwise, returns true.

You can easily get the boolean result of a statements falsiness/truthiness by doing: !!{statement}. For your example, !!0 gives false, likewise !!1 gives true.

If we were to write our own logical IS and NOT function according to JS standards, it would look like:

function logicalIs(statement) {
  if(statement === undefined) return false;
  if(statement === null) return false;
  if(statement === false) return false;
  if(statement === "") return false;
  if(statement === '') return false;
  if(statement === 0) return false;
  if(typeof(statement) === 'number' && isNaN(statement)) return false;
  // document.all: Willful violation for IE legacy reasons
  if(statement === document.all) return false; 
  return true;
}

function logicalIsNot(statement) {
  if(statement === undefined) return true;
  if(statement === null) return true;
  if(statement === false) return true;
  if(statement === "") return true;
  if(statement === '') return true;
  if(statement === 0) return true;
  if(typeof(statement) === 'number' && isNaN(statement)) return true;
  // document.all: Willful violation for IE legacy reasons
  if(statement === document.all) return true;
  return false;
}

let truthy = [true, 1, 'a', "b", [], {}, function(){}];
let falsy = [false, 0, '', "", NaN, null, undefined, document.all];

console.log('logical truthy: ', JSON.stringify(truthy.map(logicalIs)));
console.log('logical falsy: ', JSON.stringify(falsy.map(logicalIs)));

console.log('logical not truthy:', JSON.stringify(truthy.map(logicalIsNot)));
console.log('logical not falsy:', JSON.stringify(falsy.map(logicalIsNot)));

Upvotes: 1

Lucca Ferri
Lucca Ferri

Reputation: 1347

I'm a not javascript developer, but this is quite simple.

int 0 equals int 0

int 1 equals int 1

int 0 == bool false equals true (it means JS threats 0 as false and casts 0 to bool)

int 1 == bool true equals true (it means JS threats 1 as true and casts 1 to bool)

bool !0 equals true (!0 becomes true, because the opposite of true is false, and 0 is threated here as 0 because ! interprets and casts it as a boolean)

!1 equals false

As far as my javascript knowledge goes, once you use ! it will become a boolean as it tries to cast int to bool.

true && !0 == true because !0 is true.

Basically it's parsing as true && true == true thus returning boolean true, and not !0.

Upvotes: 5

Related Questions