前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库parseInt 字符串解析 陷阱
JavaScript值与类型

parseInt 有哪些坑?为什么 ['1', '2', '3'].map(parseInt) 结果不对?

parseInt 先把参数转成字符串,跳过开头空白,然后从左往右读数字,碰到第一个不合法的字符就停下,把前面读到的部分转成整数;一个都没读到才返回 NaN。坑几乎都出在「先转字符串」和第二个参数 radix 上。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#值与类型
先看核心答案读代码示例
理解线索

`parseInt` 的解析顺序

  1. 转字符串先对参数调用 String(),数字 0.0000005 会变成 '5e-7'
  2. 定进制radix 没传或为 0 时,0x 开头按十六进制,其余按十进制
  3. 贪心读取从左往右读合法数字,第一个非法字符处截断

radix 合法范围是 2~36,传 1 或 37 直接返回 NaN,传 0 等同于没传。

核心回答

先记住这个答案

parseInt(string, radix) 的规则是:先把第一个参数转成字符串,去掉开头的空白,识别正负号,然后按进制从左往右读数字字符,遇到第一个不属于该进制的字符就停,返回已经读到的整数部分。一个合法字符都没读到,返回 NaN。所以 parseInt('12px') 是 12,parseInt('px12') 是 NaN。radix 不传时只有 0x 开头会按十六进制,其余按十进制,实际写代码时应该总是传 radix。

  • 读到非法字符就停,一个都没读到才是 NaN
  • 只认 0x 前缀,0b、0o 和前导 0 都不认
  • 参数会先转成字符串,小数可能变成科学计数法
  • 永远显式传 radix,一般写 10

几个典型输入

先看一组输出,大部分坑都能在这里找到。

截断、前缀和空串JavaScript
console.log(parseInt('  42abc'))  // 跳过开头空格,读到 a 停下
console.log(parseInt('3.99'))     // 小数点不是整数字符,直接截断,不四舍五入
console.log(parseInt('abc42'))    // 第一个字符就不合法
console.log(parseInt(''))         // 什么都读不到
console.log(parseInt('0x1F'))     // 0x 前缀自动按十六进制
console.log(parseInt('0x1F', 10)) // 指定十进制后,读到 x 就停
console.log(parseInt('0b101'))    // 不认 0b,读到 b 停
console.log(parseInt('010'))      // 前导 0 不再当八进制
console.log(parseInt('1e3'))      // e 不是数字,科学计数法不认
查看输出与解释
42
3
NaN
NaN
31
0
0
10
1

有两行值得单独说。parseInt('0x1F', 10) 返回 0,因为十进制下 x 不合法,只读到了开头的 0。parseInt('010') 返回 10:在很老的引擎里前导 0 会被当成八进制得到 8,ES5 已经明确规定不再这样处理,现在所有主流浏览器都按十进制解析。能被自动识别的前缀只有 0x 和 0X,二进制的 0b、八进制的 0o 只在数字字面量和 Number() 里有效。

两道经典坑题

面试官很喜欢这两道,因为它们分别考了 radix 和「先转字符串」这两条规则。

['1', '2', '3'].map(parseInt)
结果是 [1, NaN, NaN]。map 调用回调时会传三个参数:元素、索引、数组。于是实际执行的是 parseInt('1', 0)、parseInt('2', 1)、parseInt('3', 2)。第一个 radix 是 0,等同于没传,按十进制得 1。第二个 radix 是 1,不在 2~36 的范围里,直接返回 NaN。第三个按二进制解析,二进制里只有 0 和 1,'3' 一个合法字符都没有,也是 NaN。修法是写成 .map((s) => parseInt(s, 10)),或者直接 .map(Number)。
parseInt(0.0000005) 为什么是 5?
parseInt 的第一个参数必须是字符串,数字会先经过 String() 转换。String(0.0000005) 得到 '5e-7',因为小于 1e-6 的数会用科学计数法表示。接着从左往右读,读到 5 遇到 e 停下,结果就是 5。同样的道理,parseInt(1e21) 得到 1,因为 String(1e21) 是 '1e+21'。 所以不要用 parseInt 给数字取整。数字取整用 Math.trunc、Math.floor,它们直接对数值操作,不经过字符串。
回答前,多想一步

容易答错的地方

以为 parseInt 会四舍五入
parseInt('3.99') 是 3,parseInt('-3.99') 是 -3。它只是在小数点处截断,效果相当于向 0 取整,从来不做舍入。
以为不传 radix 也没问题
对十进制字符串确实没问题,但只要数据里混进 0x 开头的值,结果就会悄悄变成十六进制。ESLint 的 radix 规则就是专门要求显式传第二个参数的。
以为超长数字串能精确解析
parseInt('9007199254740993') 得到 9007199254740992。parseInt 能读完所有数字,但结果仍然是 Number,超过 2^53 就会被舍入。需要精确处理大整数时用 BigInt('9007199254740993')。
试着用自己的话回答

面试官还会怎么问?

parseInt 和 Number() 选哪个?

看你想不想容忍多余字符。解析 '12px' 这种 CSS 值、从一段文本里取开头的数字,用 parseInt;校验用户输入必须是纯数字,用 Number(),因为 Number('12px') 会直接返回 NaN,能把脏数据暴露出来。

parseInt(null, 36) 返回什么?

返回 1112745。null 先被转成字符串 'null',而三十六进制里 n、u、l 都是合法数字,整串被当成一个三十六进制数解析了。这个例子常被用来说明「先转字符串」这条规则。

怎么把十六进制字符串转回数字?

parseInt('ff', 16) 得到 255,带不带 0x 前缀都可以,parseInt('0xff', 16) 也是 255。反过来把数字转成十六进制字符串用 (255).toString(16)。

从一道题,走向一组知识

把知识连起来

值与类型

字符串转数字,Number()、parseInt、parseFloat 和一元加号有什么区别?

parseInt 是「能读多少读多少」,Number() 是「整串都得合法」,两题放一起能看清怎么选。

值与类型

toFixed 返回什么类型?为什么 1.005.toFixed(2) 是 1.00 而不是 1.01?

有人用 parseInt 截断小数、用 toFixed 保留小数,两者都会被浮点表示和字符串转换坑到。

参考资料

  • JavaScript:值与类型参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 几个典型输入
  3. 两道经典坑题
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑