JavaScript for impatient programmers (beta)
Please support this book: buy it or donate
(Ad, please don’t block.)

13. Booleans

The primitive type boolean comprises two values:

> typeof false
'boolean'
> typeof true
'boolean'

13.1. Converting to boolean

Table 3: Converting values to booleans.
x Boolean(x)
undefined false
null false
boolean value x (no change)
number value 0 false, NaN false
other numbers true
string value '' false
other strings true
object value always true

Tbl. 3 describes how various values are converted to boolean.

13.1.1. Ways of converting to boolean

These are three ways in which you can convert an arbitrary value x to a boolean.

13.2. Falsy and truthy values

In JavaScript, you often check a value to determine if something exists. For example, a property:

if (obj.prop === undefined) {
  // obj has property .prop
}

To simplify this check, you can instead check whether the value is true when converted to boolean. That’s less precise, but can be done much more succinctly:

if (obj.prop) {
  // obj has property .prop
}

This simplified check is so popular that the following two names were created:

Consulting tbl. 3, we can make an exhaustive list of falsy values:

All other values (incl. all objects) are truthy:

> Boolean('abc')
true
> Boolean([])
true
> Boolean({})
true

13.2.1. Checking for truthiness or falsiness

if (x) {
  // x is truthy
}

if (!x) {
  // x is falsy
}

if (x) {
  // x is truthy
} else {
  // x is falsy
}

13.2.2. Use case: was a parameter provided?

A truthiness check is often used to determine if the caller of a function provided a parameter:

function func(x) {
  if (!x) {
    throw new Error('Missing parameter x');
  }
  // ···
}

On the plus side, this pattern is established and concise. It correctly throws errors for either undefined or null.

Alas, it also throws errors for all other falsy values (false, 0, NaN, '').

An alternative is to just check for undefined:

if (x === undefined) {
  throw new Error('Missing parameter x');
}

13.2.3. Use case: does a property exist?

Truthiness checks are also often used to determine if a property exists:

function readFile(fileDesc) {
  if (!fileDesc.path) {
    throw new Error('Missing property: .path');
  }
  // ···
}
readFile({ path: 'foo.txt' }); // no error

This pattern is also established and has a similar caveat: it not only throws if the property is missing, but also if it exists and has any of the falsy values.

If you truly want to check if the property exists, you have to use the in operator:

if (! ('path' in fileDesc)) {
  throw new Error('Missing property: .path');
}

  Exercise: Truthiness

exercises/booleans/truthiness_exrc.js

13.3. Conditional operator (? :)

The conditional operator is the expression version of the if statement. Its syntax is:

«condition» ? «thenExpression» : «elseExpression»

It is evaluated as follows:

The conditional operator is also called ternary operator, because it has three operands.

Examples:

> true ? 'yes' : 'no'
'yes'
> false ? 'yes' : 'no'
'no'
> '' ? 'yes' : 'no'
'no'

The following code demonstrates that, whichever of the two branches “then” and “else” is chosen via the condition – only that branch is evaluated. The other branch isn’t.

const x = (true ? console.log('then') : console.log('else'));

// Output:
// 'then'

13.4. Binary logical operators: And (&&), Or (||)

The operators && and || are value-preserving and short-circuiting. What does that mean?

Value-preservation means that operands are interpreted as booleans, but returned unchanged:

> 12 || 'hello'
12
> 0 || 'hello'
'hello'

Short-circuiting means: If the first operand already determines the result, the second operand is not evaluated. The only other operator that delays evaluating its operands is the conditional operator: Usually, all operands are evaluated before performing an operation.

For example, logical And (&&) does not evaluate its second operand if the first one is falsy:

const x = false && console.log('hello');
// No output

If the first operand is truthy, the console.log() is executed:

const x = true && console.log('hello');

// Output:
// 'hello'

13.4.1. Logical And (&&)

The expression a && b (“a And b”) is evaluated as follows:

In other words, the following two expressions are roughly equivalent:

a && b
!a ? a : b

Examples:

> false && true
false
> false && 'abc'
false

> true && false
false
> true && 'abc'
'abc'

> '' && 'abc'
''

13.4.2. Logical Or (||)

The expression a || b (“a Or b”) is evaluated as follows:

In other words, the following two expressions are roughly equivalent:

a || b
a ? a : b

Examples:

> true || false
true
> true || 'abc'
true

> false || true
true
> false || 'abc'
'abc'

> 'abc' || 'def'
'abc'

13.4.3. Default values via logical Or (||)

Sometimes you receive a value and only want to use it if it isn’t either null or undefined. Otherwise, you’d like to use a default value, as a fallback. You can do that via the || operator:

const valueToUse = valueReceived || defaultValue;

The following code shows a real-world example:

function countMatches(regex, str) {
  const matchResult = str.match(regex); // null or Array
  return (matchResult || []).length;
}

If there are one or more matches for regex inside str then .match() returns an Array. If there are no matches, it unfortunately returns null (and not the empty Array). We fix that via the || operator.

  Exercise: Default values via the Or operator (||)

exercises/booleans/default_via_or_exrc.js

13.5. Logical Not (!)

The expression !x (“Not x”) is evaluated as follows:

Examples:

> !false
true
> !true
false

> !0
true
> !123
false

> !''
true
> !'abc'
false

  Quiz

See quiz app.