How Lodash defaultTo Handles NaN Values

The Lodash _.defaultTo method offers a reliable mechanism for setting fallback values by specifically targeting NaN, null, and undefined. While standard JavaScript fallback patterns often struggle to differentiate between invalid numerical operations and legitimate falsy values, _.defaultTo evaluates the input value and gracefully substitutes a defined default whenever NaN is encountered. This article explains how _.defaultTo identifies NaN, contrasts its behavior with native JavaScript operators, and demonstrates its practical application in numeric computations.

The Challenge with NaN in Native JavaScript

In JavaScript, NaN (Not-a-Number) represents a failed numerical calculation, such as dividing zero by zero or parsing an invalid string with parseInt(). Handling NaN using native operators presents specific limitations:

How _.defaultTo Detects and Replaces NaN

The syntax for the method is:

_.defaultTo(value, defaultValue)

Internally, _.defaultTo inspects the evaluated value to determine if it should be replaced. Lodash checks whether the value is strictly undefined, null, or NaN.

Because NaN has the unique property in JavaScript of not being equal to itself (NaN === NaN evaluates to false), standard equality checks fail. Lodash handles this internally by using an equivalent of Number.isNaN() or self-inequality checks (value !== value). If this condition evaluates to true, _.defaultTo discards the NaN result and returns the specified defaultValue.

Code Example

The following example illustrates how _.defaultTo handles NaN and how it preserves valid numeric inputs like zero:

const _ = require('lodash');

// Failed calculation yielding NaN
const invalidResult = Math.sqrt(-1); 
const safeNumber = _.defaultTo(invalidResult, 0);
console.log(safeNumber); // Outputs: 0

// Native comparison: nullish coalescing fails to catch NaN
console.log(invalidResult ?? 100); // Outputs: NaN

// Preserving zero while replacing NaN
console.log(_.defaultTo(0, 10));   // Outputs: 0 (valid number preserved)
console.log(_.defaultTo(NaN, 10)); // Outputs: 10 (fallback applied)

By explicitly checking for NaN, _.defaultTo bridges the gap between the overly permissive logical OR operator and the strict nullish coalescing operator, ensuring safe numeric fallbacks without altering valid falsy data.