别再用 map(parseInt),我也是最近才发现问题出在哪

这事说出来有点尴尬。我一直以为 ['1', '2', '3'].map(parseInt) 会返回 [1, 2, 3],直到最近碰到了一个诡异的 bug,才意识到自己一直理解错了。

运行这段代码:

js 复制代码
console.log(['1', '2', '3'].map(parseInt));

你会得到:

js 复制代码
[1, NaN, NaN]

是不是感觉哪不对劲?


map 和 parseInt 怎么就掰了?

先简单回顾下两个函数的参数形式:

js 复制代码
arr.map((value, index, array) => {})
parseInt(string, radix)

重点在这里:map 会把当前值、索引、原数组都传进去。而 parseInt 的第二个参数是 进制,不是索引。

所以上面这段代码,其实执行的是:

js 复制代码
parseInt('1', 0); // 1,自动识别为十进制
parseInt('2', 1); // NaN,1进制非法
parseInt('3', 2); // NaN,2进制没有 3

结果自然就变成 [1, NaN, NaN]


正确做法其实很简单

只要你别让 parseInt 误收到第二个参数就行了。

方法一:包一层箭头函数

js 复制代码
['1', '2', '3'].map(str => parseInt(str)); // [1, 2, 3]

方法二:直接用 Number

js 复制代码
['1', '2', '3'].map(Number); // [1, 2, 3]

这个方式更直观,也更不容易踩坑。


为什么这个问题容易被忽略?

主要两个原因:

  1. 平时我们都把 parseInt 当作"字符串转数字"的函数,很少注意它的第二个参数是进制。
  2. map(parseInt) 也没有语法错误,但参数传错了,结果就全乱了。

这种问题不容易第一时间发现,尤其调试时根本不会去怀疑 map(parseInt) 这行写法。


顺带说一下:parseInt 和 map 到底是干嘛的?

parseInt 是干嘛的?

parseInt 用来把字符串转成整数:

js 复制代码
parseInt('10');      // 默认是十进制,结果 10
parseInt('10', 2);   // 二进制,结果 2
parseInt('A', 16);   // 十六进制,结果 10
parseInt('abc');     // 转不了数字,结果 NaN

注意:第二个参数是"进制",合法范围是 2 到 36。


map 是干嘛的?

map 是数组的方法,用来生成一个新数组,对每一项做处理:

js 复制代码
['1', '2', '3'].map(x => Number(x)); // [1, 2, 3]

users.map(user => ({
  ...user,
  online: true
}));

forEach 不一样,map 会返回新数组。


写法对比一览表

写法 结果 是否推荐
['1','2','3'].map(parseInt) [1, NaN, NaN] ❌ 不推荐
['1','2','3'].map(str => parseInt(str)) [1, 2, 3] ✅ 推荐
['1','2','3'].map(Number) [1, 2, 3] ✅ 推荐

总结一句话

别再用 map(parseInt),会出问题。

这不是语法错,是你传错了参数。改成箭头函数或者用 Number,就不会踩坑。


如果你也遇到过类似的"奇怪行为"

欢迎评论区一起交流。我踩过坑,你就别踩了。

如果这篇文章对你有点帮助,点个赞/收藏就当是支持一下~

相关推荐
书语时14 分钟前
ES6 Promise 状态机
前端·javascript·es6
拉不动的猪42 分钟前
管理不同权限用户的左侧菜单展示以及权限按钮的启用 / 禁用之其中一种解决方案
前端·javascript·面试
西陵1 小时前
前端框架渲染DOM的的方式你知道多少?
前端·javascript·架构
海的诗篇_1 小时前
前端开发面试题总结-JavaScript篇(一)
开发语言·前端·javascript·学习·面试
じ☆ve 清风°1 小时前
理解JavaScript中map和parseInt的陷阱:一个常见的面试题解析
开发语言·javascript·ecmascript
江城开朗的豌豆1 小时前
eval:JavaScript里的双刃剑,用好了封神,用不好封号!
前端·javascript·面试
江城开朗的豌豆2 小时前
JavaScript篇:前端定时器黑科技:不用setInterval照样玩转循环任务
前端·javascript·面试
江城开朗的豌豆2 小时前
JavaScript篇:自定义事件:让你的代码学会'打小报告'
前端·javascript·面试
lexiangqicheng3 小时前
JS-- for...in和for...of
开发语言·前端·javascript
smallluan3 小时前
JS设计模式(4):观察者模式
javascript·观察者模式·设计模式