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:
- The Nullish Coalescing Operator (
??): Only checks fornullandundefined. It treatsNaNas a defined value, meaningNaN ?? 10returnsNaN. - The Logical OR Operator (
||): Fallbacks on any falsy value. WhileNaN || 10correctly returns10, it also replaces valid values like0,false, and empty strings"", which is often undesirable when working with numbers.
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.