How Does Lodash Make its `parseInt` map-safe

381 阅读1分钟

先抛出结论:lodash 世界的 parseInt 是 map 安全的。

著名的 map 结合 parseInt bug

前端界著名的 parseInt bug:

['6', '08', '10'].map(parseInt);

// [6, NaN, 2]

为何用 lodash 的 parseInt 却是安全的,而且官方特意给出了示例

_.map(['6', '08', '10'], _.parseInt);

// => [6, 8, 10]

image.png

先从 trim 讲起

最近在做数组的 trim 操作,原本写法:

['001100', '110011'].map(val => _.trim(val))

但转念一想何不这么写,更简洁:

['001100', '110011'].map(_.trim)

完事后走路的途中突然想到,trim 有第二个参数,会当做 trim 的目标字符,即:

_.trim('110011', '1')

// => '000'

那么,结合 map 不是有 bug 吗,下标将会被当做 trim 的目标被删除掉,这是万万不可的,即:

['001100', '110011'].map(_.trim)

// => ['11', '00']

但实际上返回正确,仍然是 ["001100", "110011"]

为什么?

查看 lodash 源码发现有第三个秘密参数 guard,这是一个安全参数,当 truthy 则会省略第二个参数,故 _.trim 是 map 安全的。

官方文档并未有第三个参数的说明,因为:

The guard param is not intended for public use an is part of allowing it to work in _.map and others as an iteratee.

github.com/lodash/loda…

大胆猜测 parseInt 也有第三个安全参数,果不其然。

image.png

总结

lodash 的 trim 和 parseInt 能够被安全的当做 map 的处理函数,甚至一系列将会被 map 消费的函数都被 lodash 设计得很安全。

lodash 很强大,解决了原生 js 诸多痼疾 👍。