Exploring Falsy & Truthy Values: A Comprehensive Guide

Javascript Jan 28, 2023
Exploring Falsy & Truthy Values: A Comprehensive Guide

Comparing two things for equality can often trip up the unwary JavaScript developer, as the language has several quirks that we need to be aware of.

In this article, we'll explore why we're exploring the double-equal and triple-equal operators and the concepts of true and false values ​​in JavaScript. When you're done reading, you'll understand how JavaScript compares and how to do so realistically and accurately. Fake values ​​can help you write cleaner code.

Typing in JavaScript

JavaScript variables are loosely or dynamically typed, the language doesn't care how the value is declared or changed:

let x;
x = 1;   // x is a number
x = '1'; // x is a string
x = [1]; // x is an array

In contrast to == (loose or abstract equality), seemingly different values ​​are equivalent to true because JavaScript (effectively) converts each value to a string representation before comparing:

// all true
1 == '1';
1 == [1];
'1' == [1];

More obvious wrong results when comparing with === (strict equality), because types are considered:

// all false
1 === '1';
1 === [1];
'1' === [1];

JavaScript internally sets values ​​to one of seven primitive data types:

  • undefined (variable with no defined value)
  • Null (a single null value)
  • boolean (true or false)
  • numbers (this includes Infinity and NaN - not numbers!)
  • BigInt (integer values ​​greater than 2^53 – 1)
  • String (textual data)
  • Symbol (a unique and immutable primitive added to ES6/2015)

Everything else is an object - including arrays.

Truthy vs Falsy Values in JavaScript

In addition to the type, each value also has an inherent boolean value, often called truthy or falsy. Some of the rules that determine how non-boolean values ​​are converted to true or false values ​​are a bit odd. Understanding concepts and their impact on comparisons helps When debugging JavaScript applications.

The following values ​​are always falsy :

  • false
  • 0 (zero)
  • -0 (minus zero)
  • 0n ( BigInt zero)
  • '' `` (empty string)
  • null
  • undefined
  • NaN

Everything else is real. including:

  • '0' (a string containing a single zero)
  • 'false' (a string containing the text "false")
  • [] (an empty array)
  • {} (an empty object)
  • function(){} (an “empty” function)

Therefore, a single value can be used within a condition.

if (value) {
  // value is truthy
}
else {
  // value is falsy
  // it could be false, 0, '', null, undefined or NaN
}

You may also see document.all listed as a false value. This returns an HTMLAllCollection containing a list of all document elements. While this is considered an error in a boolean context, it is a deprecated feature and MDN advises against its use.

loose equality comparison with ==

Unexpected situations may arise when using == loose equality to compare truthy and falsy values:

The rules:

  • false Both zero and the empty string are equivalent.
  • null and undefined are equivalent to themselves and each other, but nothing else.
  • NaN is not equal to anything - including another NaN ! .
  • Infinity is true - but not comparable to true or false! .
  • Empty array is true - but comparison to true is false, comparison to false is true? ! .

Note the difference in how the various types of null values ​​are evaluated. An empty string or undefined value is false, but an empty array or object is true.

// all true
false == 0;
0 == '';
null == undefined;
[] == false;
!![0] == true;

// all false
false == null;
NaN == NaN;
Infinity == true;
[] == true;
[0] == true;

Strict equality comparison with ===

The situation is clearer when using strict equality comparisons, since the value types must match:

Strict equality comparison with ===

The only exception is NaN, which is still stubbornly not equal to everything.

Advice on using true or false values

True and false values ​​can make even the most experienced developers stand out. Those new to programming or migrating from other languages ​​have no chance! Fortunately, there are three easy steps to catch the hardest-to-find bugs when dealing with truthy and falsy variables. let's look at each in turn.

  • Avoid direct comparisons

There is rarely a need to compare two truthy and falsy values ​​when a single value is always equal to true or false:

// instead of
if (x == false) // ...
// runs if x is false, 0, '', or []

// use
if (!x) // ...
// runs if x is false, 0, '', NaN, null or undefined
  • Use === strict equality

Use the === strict equality (or !== strict inequality) comparison to compare values ​​and avoid type conversion problems:

// instead of
if (x == y) // ...
// runs if x and y are both truthy or both falsy
// e.g. x = null and y = undefined

// use
if (x === y) // ...
// runs if x and y are identical...
// except when both are NaN
  • Convert to real boolean when necessary

You can use the boolean constructor or double negatives to convert any value to a real boolean in JavaScript! .This will allow you to be absolutely sure that false is only generated by false 0 null undefined and NaN :

// instead of
if (x === y) // ...
// runs if x and y are identical...
// except when both are NaN

// use
if (Boolean(x) === Boolean(y)) // ...
// or
if (!!x === !!y) // ...
// runs if x and y are identical...
// including when either or both are NaN

Boolean constructors return true when passed a true value and false when passed a false value. This can be useful when combined with iterative methods. For example:

const truthy_values = [
  false,
  0,
  ``,
  '',
  "",
  null,
  undefined,
  NaN,
  '0',
  'false',
  [],
  {},
  function() {}
].filter(Boolean);

// Filter out falsy values and log remaining truthy values
console.log(truthy_values);