I know Lodash often adds some extra checks or niceties to functions that already exist in JavaScript but it's not clear what _.toNumber
specifically does that I wouldn't get with parseInt
.
I'd prefer to use Lodash only when it provides benefits that aren't there with existing JavaScript functions but I can't see any in this case.
I know Lodash often adds some extra checks or niceties to functions that already exist in JavaScript but it's not clear what _.toNumber
specifically does that I wouldn't get with parseInt
.
I'd prefer to use Lodash only when it provides benefits that aren't there with existing JavaScript functions but I can't see any in this case.
Share Improve this question asked Jun 11, 2019 at 19:03 Brady DowlingBrady Dowling 5,5324 gold badges41 silver badges67 bronze badges2 Answers
Reset to default 19I think it is much better to simply look at the _.toNumber source and that would practically answer your question:
function toNumber(value) {
if (typeof value == 'number') {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject(value)) {
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = value.replace(reTrim, '');
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: (reIsBadHex.test(value) ? NAN : +value);
}
As you can see it does a bunch of other things in comparison to parseInt. To be more specific:
console.log(_.toNumber(1), parseInt(1)) // same
console.log(_.toNumber('1'), parseInt('1')) // same
console.log(_.toNumber('b'), parseInt('b')) // same
console.log(_.toNumber({}), parseInt({})) // same
console.log(_.toNumber(' 1 '), parseInt(' 1 ')) // same
console.log(_.toNumber([1]), parseInt([1])) // same
console.log(_.toNumber(' 1a1 '), parseInt(' 1a1 ')) // NaN 1
console.log(_.toNumber([1,2]), parseInt([1,2])) // NaN 1
console.log(_.toNumber(false), parseInt(false)) // 0 NaN
console.log(_.toNumber(!0), parseInt(!0)) // 1 NaN
console.log(_.toNumber(!!0), parseInt(!!0)) // 0 NaN
console.log(_.toNumber(5e-324), parseInt(5e-324)) // 5e-324 5
console.log(_.toNumber(5.5), parseInt(5.5)) // 5.5 5
console.log(_.toNumber(null), parseInt(null)) // 0 NaN
console.log(_.toNumber(Infinity),parseInt(Infinity)) // Infinity NaN
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
So to summarize _.isNumber
gives you more expected / consistent
and I would argue safer
results when it comes to parsing input with arrays, decimals, falsy values and strings. It would check the entire input vs parseInt
which only cares about the first valid value as you can see from the examples above. It also handles better the negate operator (!
) etc.
So overall it does have its uses vs parseInt
Note: What is a gotcha here is that both _.toNumber
and parseInt
return NaN
for undefined
which considering how _.toNumber
deals with the rest of the falsy values one would expect to return 0
vs NaN
:
console.log(_.toNumber(undefined), parseInt(undefined)) // NaN NaN
_.toNumber
converts a given input to a number if such a conversion is possible, otherwise returns NaN
. The parseInt
and parseFloat
methods also work in same manner (the former will only return integers though), however, they are much more lax in their parsing rules. _.toNumber is significantly more restrictive.
For eg, with same input '5.2a'
, parseInt
would return 5
, parseFloat
would return 5.2
, and _.toNumber
would return NaN
. The former two ignore everything after the first unrecognised character and return the number formed by all parsed characters till that point. The last one however returns NaN if an unrecognised character is encountered.
_.toNumber
is comparable and functionally same to Number
function.