先抛出结论: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]
先从 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
guardparam is not intended for public use an is part of allowing it to work in_.mapand others as an iteratee.
大胆猜测 parseInt 也有第三个安全参数,果不其然。
总结
lodash 的 trim 和 parseInt 能够被安全的当做 map 的处理函数,甚至一系列将会被 map 消费的函数都被 lodash 设计得很安全。
lodash 很强大,解决了原生 js 诸多痼疾 👍。