Lodash _.lte Type Coercion: Boolean vs Number
When the Lodash library executes _.lte to compare a
boolean against a number, it coerces the boolean operand into a numeric
value before evaluating the relational condition. Internally, Lodash
converts any non-string operands to numbers using JavaScript's unary
plus (+) operator, causing true to become
1 and false to become 0. Once
both values are converted to numeric primitives, _.lte
performs standard numerical less-than-or-equal comparison
(<=).
Lodash's Relational Operation Mechanism
Lodash implements relational methods like _.lte,
_.lt, _.gte, and _.gt using an
internal helper function called createRelationalOperation.
This helper checks the types of both arguments before performing the
comparison:
function createRelationalOperation(operator) {
return function(value, other) {
if (!(typeof value == 'string' && typeof other == 'string')) {
value = +value;
other = +other;
}
return operator(value, other);
};
}Because a boolean and a number do not satisfy the condition of both
being strings, Lodash executes the else branch, applying
+value and +other.
The Coercion Rules Applied
The unary + operator invokes ECMAScript's internal
ToNumber abstract operation on each operand:
- Boolean Conversion:
trueevaluates to1falseevaluates to0
- Number Conversion:
- Numeric values remain unchanged (e.g.,
+5evaluates to5).
- Numeric values remain unchanged (e.g.,
After coercion, Lodash evaluates the comparison using the native
<= operator on the resulting numbers.
Practical Examples
Comparing true to
Numbers
Since true coerces to 1:
_.lte(true, 2)becomes1 <= 2, returningtrue._.lte(true, 1)becomes1 <= 1, returningtrue._.lte(true, 0)becomes1 <= 0, returningfalse.
Comparing false to
Numbers
Since false coerces to 0:
_.lte(false, 1)becomes0 <= 1, returningtrue._.lte(false, 0)becomes0 <= 0, returningtrue._.lte(false, -1)becomes0 <= -1, returningfalse.
Reversing Argument Order
The position of the operands determines which value is compared against which, but the coercion rules remain identical:
_.lte(0, true)becomes0 <= 1, returningtrue._.lte(2, true)becomes2 <= 1, returningfalse._.lte(0, false)becomes0 <= 0, returningtrue.
Behavior with NaN
If the number argument is NaN, coercion of
NaN yields NaN. In JavaScript, any relational
comparison involving NaN (such as 1 <= NaN
or NaN <= 1) returns false. Consequently,
both _.lte(true, NaN) and _.lte(false, NaN)
will return false.