Lodash toInteger: Removing Decimals Without Rounding
The _.toInteger method in the Lodash JavaScript library
converts inputs into integers by strictly stripping away fractional
decimal values rather than executing standard rounding algorithms.
Instead of utilizing functions such as Math.round() or
Math.floor(), Lodash normalizes the input to a finite
number and executes a remainder-based truncation using the modulo
operator. This article explains the underlying source logic of
_.toInteger, demonstrating how arithmetic subtraction
enforces integer truncation toward zero across both positive and
negative values.
The Source Implementation
Lodash defines toInteger through a concise,
high-performance function that relies on the internal
toFinite helper:
function toInteger(value) {
const result = toFinite(value);
const remainder = result % 1;
return remainder ? result - remainder : result;
}This implementation bypasses native rounding methods entirely, achieving strict decimal truncation through two distinct steps: input normalization and remainder subtraction.
Step 1: Input
Normalization via toFinite
Before any arithmetic manipulation occurs, the input value is passed
through toFinite(). This conversion layer handles
non-numeric types, edge cases, and boundary constraints:
- Non-numeric values (such as
null,undefined, or invalid strings) andNaNare coerced to0. - Numeric strings (e.g.,
'42.85') are cast to primitive numbers. - Positive and negative
Infinityare clamped toNumber.MAX_VALUE(1.7976931348623157e+308) and-Number.MAX_VALUErespectively.
Once toFinite resolves, the function guarantees a clean,
finite floating-point number.
Step 2: Remainder Calculation via Modulo
To isolate the fractional component without invoking rounding logic, Lodash calculates:
const remainder = result % 1;In JavaScript, the modulo operator (%) returns the
remainder of the division between the left operand and the right operand
while preserving the sign of the dividend. Dividing any floating-point
number by 1 isolates everything past the decimal point:
- For
4.9:4.9 % 1produces0.9(accounting for floating-point inaccuracies). - For
-4.9:-4.9 % 1produces-0.9. - For
5.0:5.0 % 1produces0.
Step 3: Subtraction and Truncation
After determining the remainder, the function evaluates whether a fractional part exists:
return remainder ? result - remainder : result;If remainder is non-zero, Lodash subtracts that
remainder directly from the original number:
- For
4.9:4.9 - 0.9 = 4 - For
-4.9:-4.9 - (-0.9) = -4
By subtracting the fractional remainder, the number is always shifted
toward zero, producing identical behavior to ES6's
Math.trunc().
Why Lodash Avoids Standard Rounding Methods
Lodash deliberately avoids Math.round(),
Math.floor(), and Math.ceil() because each of
these methods shifts fractional values based on magnitude or direction
rather than cleanly discarding the decimal:
Math.round(4.9)yields5, which changes the base integer value.Math.floor(-4.2)rounds downward to-5, failing to maintain symmetry with positive integer truncation.Math.trunc()was introduced in ECMAScript 2015 (ES6). Lodash’s algebraic approach (result - remainder) ensured backward compatibility with older JavaScript engines (such as ES3 and ES5 environments) without requiring polyfills, while providing deterministic integer conversion that strictly discards decimal fractions.