Skip to content

map和parseInt的妙用与陷阱 🤔 ​

一个经典面试题 ​

下面这段代码的运行结果是什么?

js
['1', '2', '3'].map(parseInt)

答案是:[1, NaN, NaN]

深入理解原因 🔍 ​

1. map 方法的工作机制 ​

map 方法会为数组的每个元素调用一次回调函数,并传入三个参数:

  • 当前元素值
  • 当前索引
  • 原数组
js
['1', '2', '3'].map((element, index, array) => {
  console.log(`元素: ${element}, 索引: ${index}, 数组: ${array}`);
  return element;
});

2. parseInt 函数的参数 ​

parseInt(string, radix) 接收两个参数:

  • string: 要被解析的字符串
  • radix: 进制数(范围:2-36)

解析过程详解 ⚡ ​

当 ['1', '2', '3'].map(parseInt) 执行时,实际上发生了以下转换:

js
// 实际执行过程
parseInt('1', 0)  // 输出: 1    (radix 为 0 时,按十进制解析)
parseInt('2', 1)  // 输出: NaN  (radix 为 1 无效,必须在 2-36 之间)
parseInt('3', 2)  // 输出: NaN  (二进制不能有 3)

正确使用方式 ✅ ​

如果想要正确地将字符串数组转换为数字数组,可以使用以下方法:

js
// 方法 1:使用单参数箭头函数
['1', '2', '3'].map(num => parseInt(num))

// 方法 2:使用 Number 构造函数
['1', '2', '3'].map(Number)

// 方法 3:使用一元加号操作符
['1', '2', '3'].map(n => +n)

补充知识点 📚 ​

  1. parseInt 的进制说明:

    • 当 radix 为 0 或未指定时:
      • 如果字符串以 "0x" 开头,按 16 进制解析
      • 如果字符串以 "0" 开头,在 ES5 之前按 8 进制解析,ES5 之后按 10 进制解析
      • 其他情况按 10 进制解析
  2. 进制范围说明:

    • 最小值为 2(二进制)
    • 最大值为 36(0-9 + a-z,共 36 个字符)
    • 超出范围返回 NaN

实践建议 💡 ​

  1. 转换数字时,优先使用 Number() 或一元加号操作符,更直观且不易出错
  2. 使用 parseInt 时,建议始终显式指定进制参数
  3. 处理数组转换时,使用明确的回调函数而不是直接传入 parseInt
js
// 推荐写法
const numbers = ['1', '2', '3'].map(str => parseInt(str, 10));

这样可以避免意外的进制转换问题,代码也更容易维护和理解。